use indexmap::IndexMap;
use schematic_types::*;
use std::collections::HashSet;
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) -> RenderResult<O>;
fn render_boolean(&mut self, boolean: &BooleanType) -> RenderResult<O>;
fn render_enum(&mut self, enu: &EnumType) -> RenderResult<O>;
fn render_float(&mut self, float: &FloatType) -> RenderResult<O>;
fn render_integer(&mut self, integer: &IntegerType) -> RenderResult<O>;
fn render_literal(&mut self, literal: &LiteralType) -> RenderResult<O>;
fn render_null(&mut self) -> RenderResult<O>;
fn render_object(&mut self, object: &ObjectType) -> RenderResult<O>;
fn render_reference(&mut self, reference: &str) -> RenderResult<O>;
fn render_string(&mut self, string: &StringType) -> RenderResult<O>;
fn render_struct(&mut self, structure: &StructType) -> RenderResult<O>;
fn render_tuple(&mut self, tuple: &TupleType) -> RenderResult<O>;
fn render_union(&mut self, uni: &UnionType) -> RenderResult<O>;
fn render_unknown(&mut self) -> RenderResult<O>;
fn render_schema(&mut self, schema: &SchemaType) -> RenderResult<O> {
if let Some(name) = schema.get_name() {
if self.is_reference(name) {
return self.render_reference(name);
}
}
self.render_schema_without_reference(schema)
}
fn render_schema_without_reference(&mut self, schema: &SchemaType) -> RenderResult<O> {
match schema {
SchemaType::Null => self.render_null(),
SchemaType::Unknown => self.render_unknown(),
SchemaType::Array(array) => self.render_array(array),
SchemaType::Boolean(boolean) => self.render_boolean(boolean),
SchemaType::Enum(enu) => self.render_enum(enu),
SchemaType::Float(float) => self.render_float(float),
SchemaType::Integer(integer) => self.render_integer(integer),
SchemaType::Literal(literal) => self.render_literal(literal),
SchemaType::Object(object) => self.render_object(object),
SchemaType::Struct(structure) => self.render_struct(structure),
SchemaType::String(string) => self.render_string(string),
SchemaType::Tuple(tuple) => self.render_tuple(tuple),
SchemaType::Union(uni) => self.render_union(uni),
}
}
fn render(
&mut self,
schemas: &IndexMap<String, SchemaType>,
references: &HashSet<String>,
) -> RenderResult;
}