///|
pub(all) enum Value {
Null
Bool(Bool)
Number(Double)
String(String)
Array(Array[Value])
Object(Map[String, Value])
} derive(Eq, Debug)
///|
pub fn from_json(value : Json) -> Value {
match value {
Json::Null => Null
Json::True => Bool(true)
Json::False => Bool(false)
Json::Number(n, ..) => Number(n)
Json::String(s) => String(s)
Json::Array(items) => Array(items.map(from_json))
Json::Object(fields) => Object(fields.map(fn(_, v) { from_json(v) }))
}
}
///|
pub fn Value::to_json(self : Value) -> Json {
match self {
Null => Json::null()
Bool(b) => Json::boolean(b)
Number(n) => Json::number(n)
String(s) => Json::string(s)
Array(items) => Json::array(items.map(fn(v) { v.to_json() }))
Object(fields) => Json::object(fields.map(fn(_, v) { v.to_json() }))
}
}
///|
pub fn Value::stringify(self : Value) -> String {
self.to_json().stringify()
}
///|
/// Parses JSON text into a semantic value.
pub fn parse(source : StringView) -> Value raise {
from_json(@json.parse(source))
}
///|
pub fn execute(request : Json) -> Json raise {
run(from_json(request)).to_json()
}
///|
/// Maps every leaf (a scalar or an empty container) to its JSON Pointer
/// path. The root path is "" and keys are escaped as in RFC 6901.
pub fn Value::flatten(self : Value) -> Map[String, Value] {
let result : Map[String, Value] = Map([])
fn walk(value : Value, path : String) -> Unit {
match value {
Object(fields) if !fields.is_empty() =>
for key, child in fields {
walk(child, path + "/" + escape_key(key))
}
Array(items) if !items.is_empty() =>
for i, item in items {
walk(item, path + "/" + i.to_string())
}
leaf => result[path] = leaf
}
}
walk(self, "")
result
}
///|
/// Returns the value at a JSON Pointer path, raising an input error when
/// the path is malformed or absent.
pub fn Value::pointer(self : Value, path : String) -> Value raise {
at(self, path)
}
///|
/// Canonical JSON text: object keys in UTF-16 code unit order, no
/// whitespace, arrays in order.
pub fn Value::canonical(self : Value) -> String {
canonical(self)
}