use indexmap::IndexMap;
use schematic_types::*;
pub type RenderResult<T = String> = miette::Result<T>;
pub trait SchemaRenderer<O = String> {
fn is_reference(&self, name: &str) -> bool;
fn render_array(&mut self, array: &ArrayType, schema: &Schema) -> RenderResult<O>;
fn render_boolean(&mut self, boolean: &BooleanType, schema: &Schema) -> RenderResult<O>;
fn render_enum(&mut self, enu: &EnumType, schema: &Schema) -> RenderResult<O>;
fn render_float(&mut self, float: &FloatType, schema: &Schema) -> RenderResult<O>;
fn render_integer(&mut self, integer: &IntegerType, schema: &Schema) -> RenderResult<O>;
fn render_literal(&mut self, literal: &LiteralType, schema: &Schema) -> RenderResult<O>;
fn render_null(&mut self, schema: &Schema) -> RenderResult<O>;
fn render_object(&mut self, object: &ObjectType, schema: &Schema) -> RenderResult<O>;
fn render_reference(&mut self, reference: &str, schema: &Schema) -> RenderResult<O>;
fn render_string(&mut self, string: &StringType, schema: &Schema) -> RenderResult<O>;
fn render_struct(&mut self, structure: &StructType, schema: &Schema) -> RenderResult<O>;
fn render_tuple(&mut self, tuple: &TupleType, schema: &Schema) -> RenderResult<O>;
fn render_union(&mut self, uni: &UnionType, schema: &Schema) -> RenderResult<O>;
fn render_unknown(&mut self, schema: &Schema) -> RenderResult<O>;
fn render_schema(&mut self, schema: &Schema) -> RenderResult<O> {
if let Some(name) = &schema.name {
if self.is_reference(name) {
return self.render_reference(name, schema);
}
}
self.render_schema_without_reference(schema)
}
fn render_schema_without_reference(&mut self, schema: &Schema) -> RenderResult<O> {
match &schema.ty {
SchemaType::Null => self.render_null(schema),
SchemaType::Unknown => self.render_unknown(schema),
SchemaType::Array(array) => self.render_array(array, schema),
SchemaType::Boolean(boolean) => self.render_boolean(boolean, schema),
SchemaType::Enum(enu) => self.render_enum(enu, schema),
SchemaType::Float(float) => self.render_float(float, schema),
SchemaType::Integer(integer) => self.render_integer(integer, schema),
SchemaType::Literal(literal) => self.render_literal(literal, schema),
SchemaType::Object(object) => self.render_object(object, schema),
SchemaType::Struct(structure) => self.render_struct(structure, schema),
SchemaType::String(string) => self.render_string(string, schema),
SchemaType::Tuple(tuple) => self.render_tuple(tuple, schema),
SchemaType::Union(uni) => self.render_union(uni, schema),
SchemaType::Reference(name) => self.render_reference(name, schema),
}
}
fn render(&mut self, schemas: IndexMap<String, Schema>) -> RenderResult;
}