///|
pub struct ChildType {
multiple : Bool
required : Bool
types : Array[NodeType]
} derive(ToJson, Show)
///|
impl @json.FromJson for ChildType with from_json(
json : Json,
path : @json.JsonPath,
) -> ChildType raise @json.JsonDecodeError {
match json {
{
"multiple": True
| False as multiple,
"required": True
| False as required,
"types": types,
..
} =>
ChildType::{
multiple: @json.from_json(multiple, path=path.add_key("multiple")),
required: @json.from_json(required, path=path.add_key("required")),
types: @json.from_json(types, path=path.add_key("types")),
}
json => raise @json.JsonDecodeError((path, "Invalid child type: \{json}"))
}
}
///|
pub enum NodeTypePayload {
Empty
Supertype(subtypes~ : Array[NodeType])
Normal(fields~ : Map[String, ChildType], children~ : ChildType)
} derive(Show)
///|
pub struct NodeType {
type_ : String
named : Bool
payload : NodeTypePayload
} derive(Show)
///|
pub impl @json.FromJson for NodeType with from_json(
json : Json,
path : @json.JsonPath,
) -> NodeType raise @json.JsonDecodeError {
match json {
{
"type": String(type_),
"named": True
| False as named,
"subtypes": subtypes,
..
} =>
NodeType::{
type_,
named: @json.from_json(named, path=path.add_key("named")),
payload: NodeTypePayload::Supertype(
subtypes=@json.from_json(subtypes, path=path.add_key("subtypes")),
),
}
{
"type": String(type_),
"named": True
| False as named,
"fields": fields,
"children": children,
..
} =>
NodeType::{
type_,
named: @json.from_json(named, path=path.add_key("named")),
payload: NodeTypePayload::Normal(
fields=@json.from_json(fields, path=path.add_key("fields")),
children=@json.from_json(children, path=path.add_key("children")),
),
}
{ "type": String(type_), "named": True | False as named, .. } =>
NodeType::{
type_,
named: @json.from_json(named, path=path.add_key("named")),
payload: NodeTypePayload::Empty,
}
json => raise @json.JsonDecodeError((path, "Invalid node type: \{json}"))
}
}
///|
pub impl ToJson for NodeType with to_json(self : NodeType) -> Json {
let type_ = self.type_.to_json()
let named = self.named.to_json()
match self.payload {
Supertype(subtypes~) => {
let subtypes = subtypes.to_json()
{ "type": type_, "named": named, "subtypes": subtypes }
}
Empty => { "type": type_, "named": named }
Normal(fields~, children~) => {
let fields = fields.to_json()
let children = children.to_json()
{ "type": type_, "named": named, "fields": fields, "children": children }
}
}
}
///|
pub struct NodeTypes(Array[NodeType]) derive(@json.FromJson, ToJson, Show)
///|
pub fn NodeTypes::from_json(
json : Json,
) -> NodeTypes raise @json.JsonDecodeError {
@json.from_json(json)
}