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