Can extract additional informations

This commit is contained in:
Pierre HUBERT 2023-02-02 14:44:25 +01:00
parent 8044e1618d
commit ca359c20e8

View File

@ -34,8 +34,13 @@ fn expect_schema_object(s: &Schema) -> &SchemaObject {
pub enum NodeType {
Null,
Boolean,
Array { item: Box<TreeNode> },
Object { children: Vec<TreeNode> },
Array {
item: Box<TreeNode>,
},
Object {
required: Option<Vec<String>>,
children: Vec<TreeNode>,
},
String,
Number,
Integer,
@ -46,11 +51,17 @@ pub struct TreeNode {
pub name: String,
#[serde(flatten)]
pub r#type: NodeType,
#[serde(skip_serializing_if = "Option::is_none")]
pub description: Option<String>,
#[serde(skip_serializing_if = "Vec::is_empty")]
pub examples: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub r#enum: Option<Vec<String>>,
}
impl TreeNode {
/// Merge two TreeNode
pub fn merge_with(&self, other: &Self) -> Self {
pub fn merge_with(self, other: Self) -> Self {
if !matches!(self.r#type, NodeType::String | NodeType::Object { .. }) {
panic!("Cannot merge!");
}
@ -59,17 +70,36 @@ impl TreeNode {
panic!("Cannot merge other!");
}
let r#type = match (&self.r#type, &other.r#type) {
let r#type = match (self.r#type, other.r#type) {
(NodeType::String, NodeType::String) => NodeType::String,
(NodeType::String, NodeType::Object { children })
| (NodeType::Object { children }, NodeType::String) => NodeType::Object {
children: children.clone(),
},
(NodeType::String, NodeType::Object { children, required })
| (NodeType::Object { children, required }, NodeType::String) => {
NodeType::Object { children, required }
}
(NodeType::Object { children: c1 }, NodeType::Object { children: c2 }) => {
let mut children = c1.clone();
children.append(&mut c2.clone());
NodeType::Object { children }
(
NodeType::Object {
children: c1,
required: r1,
},
NodeType::Object {
children: mut c2,
required: r2,
},
) => {
let mut children = c1;
children.append(&mut c2);
let mut required = r1.unwrap_or_default();
required.append(&mut r2.unwrap_or_default());
NodeType::Object {
children,
required: match required.is_empty() {
true => None,
false => Some(required),
},
}
}
(_, _) => unreachable!(),
@ -78,6 +108,12 @@ impl TreeNode {
TreeNode {
name: self.name.to_string(),
r#type,
description: other.description.or(self.description),
examples: match other.examples.is_empty() {
true => self.examples,
false => other.examples,
},
r#enum: other.r#enum.or(self.r#enum),
}
}
}
@ -113,7 +149,7 @@ fn build_tree_schema(
for other in all_of.iter().skip(1) {
let other = build_tree_schema(expect_schema_object(other), struct_name, components);
tree = tree.merge_with(&other);
tree = tree.merge_with(other);
}
return tree;
@ -132,9 +168,8 @@ fn build_tree_schema(
InstanceType::Null => NodeType::Null,
InstanceType::Boolean => NodeType::Boolean,
InstanceType::Object => {
let children = schema
.object
.as_ref()
let object = schema.object.as_ref();
let children = object
.map(|s| s.properties.clone())
.unwrap_or_default()
.iter()
@ -143,7 +178,13 @@ fn build_tree_schema(
build_tree_schema(o, e.0, components)
})
.collect::<Vec<_>>();
NodeType::Object { children }
let required = object
.as_ref()
.map(|o| &o.required)
.map(|r| r.iter().map(|s| s.to_string()).collect());
NodeType::Object { children, required }
}
InstanceType::Array => {
let item = expect_schema_object(expect_single(
@ -162,8 +203,20 @@ fn build_tree_schema(
InstanceType::Integer => NodeType::Integer,
};
let metadata = schema.metadata.clone().unwrap_or_default();
TreeNode {
name: struct_name.to_string(),
r#type,
description: metadata.description,
examples: metadata
.examples
.iter()
.map(|v| v.to_string())
.collect::<Vec<_>>(),
r#enum: schema
.enum_values
.as_ref()
.map(|v| v.iter().map(|v| v.to_string()).collect()),
}
}