use serde_json::{json, Value};
use crate::genson_rs::node::{DataType, SchemaNode};
const DEFAULT_SCHEMA_URI: &str = "http://json-schema.org/schema#";
const NULL_SCHEMA_URI: &str = "NULL";
pub struct SchemaBuilder {
schema_uri: Option<String>,
root_node: SchemaNode,
}
impl SchemaBuilder {
pub fn new(schema_uri: Option<&str>) -> Self {
let root_node: SchemaNode = SchemaNode::new();
if let Some(uri) = schema_uri {
if uri == "AUTO" {
SchemaBuilder {
schema_uri: None,
root_node,
}
} else {
SchemaBuilder {
schema_uri: Some(uri.to_string()),
root_node,
}
}
} else {
SchemaBuilder {
schema_uri: Some(NULL_SCHEMA_URI.to_string()),
root_node,
}
}
}
pub fn add_schema(&mut self, mut schema: Value) {
if let Value::Object(ref mut schema_obj) = schema {
if schema_obj.contains_key("$schema") && self.schema_uri.is_none() {
self.schema_uri = Some(schema_obj["$schema"].as_str().unwrap().to_string());
schema_obj.remove("$schema");
}
self.root_node.add_schema(DataType::Schema(&schema));
} else {
panic!("Invalid schema type - must be a valid JSON object")
}
}
pub fn add_schema_node(&mut self, node: SchemaNode) {
self.root_node.add_schema(DataType::SchemaNode(&node));
}
pub fn add_object(&mut self, object: &simd_json::BorrowedValue) {
self.root_node.add_object(DataType::Object(object));
}
pub fn to_schema(&self) -> Value {
let mut base_schema = self.get_base_schema();
let base_schema_map = base_schema.as_object_mut().unwrap();
let node_schema = self.root_node.to_schema();
let node_schema_map = node_schema.as_object().unwrap();
for (key, value) in node_schema_map.iter() {
base_schema_map.insert(key.to_string(), value.clone());
}
base_schema
}
fn get_base_schema(&self) -> Value {
if let Some(uri) = &self.schema_uri {
if uri == NULL_SCHEMA_URI {
json!({})
} else {
json!({"$schema": uri})
}
} else {
json!({"$schema": DEFAULT_SCHEMA_URI})
}
}
pub fn to_json(&self) -> String {
let schema = self.to_schema();
schema.to_string()
}
}