///|
/// Require this value to be JSON `null`.
pub fn Value::null(self : Value) -> Unit raise Invalid {
match self.json {
Null => ()
other => err(self.path, "expected null, got \{json_kind(other)}")
}
}
///|
/// Convert this value to `Bool`.
pub fn Value::bool(self : Value) -> Typed[Bool] raise Invalid {
match self.json {
True => Typed::new(true, self.path)
False => Typed::new(false, self.path)
other => err(self.path, "expected boolean, got \{json_kind(other)}")
}
}
///|
/// Convert this value to `Int`.
///
/// JSON numbers must be finite integers in the 32-bit range.
pub fn Value::int(self : Value) -> Typed[Int] raise Invalid {
let n = expect_integer(self)
if n > 2147483647.0 || n < -2147483648.0 {
err(self.path, "integer overflow")
}
Typed::new(n.to_int(), self.path)
}
///|
/// Convert this value to `Int64`.
///
/// JSON numbers must be finite integers in the 64-bit range.
pub fn Value::int64(self : Value) -> Typed[Int64] raise Invalid {
let n = expect_integer(self)
// 2^63 is exact in Double; Int64.MAX = 2^63-1 is not.
if n >= 9223372036854775808.0 || n < -9223372036854775808.0 {
err(self.path, "integer overflow")
}
Typed::new(n.to_int64(), self.path)
}
///|
/// Convert this value to `Double`.
///
/// JSON numbers that overflow to infinity are rejected.
pub fn Value::double(self : Value) -> Typed[Double] raise Invalid {
match self.json {
Number(n, ..) => {
if n.is_nan() || n.is_inf() {
err(self.path, "must be finite")
}
Typed::new(n, self.path)
}
other => err(self.path, "expected number, got \{json_kind(other)}")
}
}
///|
/// Convert this value to `String`.
pub fn Value::string(self : Value) -> Typed[String] raise Invalid {
match self.json {
String(s) => Typed::new(s, self.path)
other => err(self.path, "expected string, got \{json_kind(other)}")
}
}
///|
/// Convert this value to an array of `Value`s.
pub fn Value::array(self : Value) -> Typed[Array[Value]] raise Invalid {
match self.json {
Array(items) => {
let values = items.mapi(fn(i, item) {
{ json: item, path: Path::Index(self.path, i), }
})
Typed::new(values, self.path)
}
other => err(self.path, "expected array, got \{json_kind(other)}")
}
}
///|
fn expect_integer(value : Value) -> Double raise Invalid {
match value.json {
Number(n, ..) => {
if n != n.trunc() {
err(value.path, "expected integer")
}
n
}
other => err(value.path, "expected integer, got \{json_kind(other)}")
}
}