Enforce unique subschema names

This commit is contained in:
Graham Esau 2019-08-04 10:11:56 +01:00
parent 2e580cb914
commit 4f9956631e

View file

@ -1,8 +1,9 @@
use crate::make_schema::MakeSchema; use crate::make_schema::MakeSchema;
use crate::schema::*; use crate::schema::*;
use core::any::{type_name, TypeId}; use core::any::TypeId;
use std::collections::HashMap as Map; use std::collections::BTreeMap as Map;
use std::collections::HashSet as Set; use std::collections::BTreeSet as Set;
use std::iter::FromIterator;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub struct SchemaGenerator { pub struct SchemaGenerator {
@ -43,14 +44,20 @@ impl SchemaGenerator {
.into() .into()
} }
pub fn definitions(&self) -> Map<String, Schema> {
Map::from_iter(self.definitions.values().cloned())
}
pub fn into_definitions(self) -> Map<String, Schema> {
Map::from_iter(self.definitions.into_iter().map(|(_, v)| v))
}
pub fn root_schema_for<T: MakeSchema>(&mut self) -> Schema { pub fn root_schema_for<T: MakeSchema>(&mut self) -> Schema {
let schema = T::make_schema(self); let schema = T::make_schema(self);
if let Schema::Object(mut o) = schema { if let Schema::Object(mut o) = schema {
o.schema = Some("http://json-schema.org/draft-07/schema#".to_owned()); o.schema = Some("http://json-schema.org/draft-07/schema#".to_owned());
o.title = Some(T::schema_name()); o.title = Some(T::schema_name());
for (_, (name, schema)) in self.definitions.iter() { o.definitions.extend(self.definitions());
o.definitions.insert(name.clone(), schema.clone());
}
return Schema::Object(o); return Schema::Object(o);
} }
schema schema
@ -61,17 +68,23 @@ impl SchemaGenerator {
if let Schema::Object(mut o) = schema { if let Schema::Object(mut o) = schema {
o.schema = Some("http://json-schema.org/draft-07/schema#".to_owned()); o.schema = Some("http://json-schema.org/draft-07/schema#".to_owned());
o.title = Some(T::schema_name()); o.title = Some(T::schema_name());
for (_, (name, schema)) in self.definitions { o.definitions.extend(self.into_definitions());
o.definitions.insert(name, schema);
}
return Schema::Object(o); return Schema::Object(o);
} }
schema schema
} }
fn make_unique_name<T: MakeSchema>(&mut self) -> String { fn make_unique_name<T: MakeSchema>(&mut self) -> String {
T::schema_name() let base_name = T::schema_name();
// TODO remove namespace, remove special chars // TODO remove namespace, remove special chars
// TODO enforce uniqueness if self.names.contains(&base_name) {
for i in 2.. {
let name = format!("{}{}", base_name, i);
if self.names.contains(&name) {
return name;
}
}
}
base_name
} }
} }