Can extract additional informations
This commit is contained in:
		
							
								
								
									
										87
									
								
								src/lib.rs
									
									
									
									
									
								
							
							
						
						
									
										87
									
								
								src/lib.rs
									
									
									
									
									
								
							| @@ -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()), | ||||
|     } | ||||
| } | ||||
|   | ||||
		Reference in New Issue
	
	Block a user