use super::DefinitionDoc;
use super::definitions::Definitions;
use crate::model::value::KindName;
use crate::schema::Shape;
#[derive(Debug, Clone, PartialEq, crate::Schema)]
#[data(tag = "kind")]
pub enum ShapeNode {
Any,
Bool,
Int {
min: i64,
max: i64,
},
Float {
bits: u32,
},
String,
Atom,
Bytes,
Ref {
of: Vec<KindName>,
id: Box<ShapeNode>,
},
Named {
name: String,
of: Box<ShapeNode>,
},
List {
of: Box<ShapeNode>,
},
Map {
of: Box<ShapeNode>,
},
Optional {
of: Box<ShapeNode>,
},
Def {
name: String,
},
}
impl ShapeNode {
pub(super) fn of(shape: &Shape, defs: &mut Definitions) -> ShapeNode {
let mut inner = |s: Shape| Box::new(ShapeNode::of(&s, defs));
match shape {
Shape::Any => ShapeNode::Any,
Shape::Bool => ShapeNode::Bool,
Shape::Int { min, max } => ShapeNode::Int {
min: *min,
max: *max,
},
Shape::Float { bits } => ShapeNode::Float { bits: *bits },
Shape::Str => ShapeNode::String,
Shape::Atom => ShapeNode::Atom,
Shape::Bytes => ShapeNode::Bytes,
Shape::Ref { kinds, id } => ShapeNode::Ref {
of: kinds.iter().filter_map(|k| KindName::new(k).ok()).collect(),
id: inner(id()),
},
Shape::Named(n) => ShapeNode::Named {
name: n.name().to_owned(),
of: inner(n.stored()),
},
Shape::List(s) => ShapeNode::List { of: inner(s()) },
Shape::Map(s) => ShapeNode::Map { of: inner(s()) },
Shape::Optional(s) => ShapeNode::Optional { of: inner(s()) },
Shape::Struct(s) => DefinitionDoc::define_struct(s, defs),
Shape::Enum(e) => DefinitionDoc::define_enum(e, defs),
}
}
}