|
1 |
| -mod hints; |
| 1 | +mod hint_set; |
2 | 2 |
|
3 |
| -pub use hints::Hints; |
| 3 | +pub use hint_set::HintSet; |
| 4 | + |
| 5 | +#[derive(Debug)] |
| 6 | +pub struct Hints<'a> { |
| 7 | + values: HintSet<'a>, |
| 8 | + discriminator: HintSet<'a>, |
| 9 | +} |
| 10 | + |
| 11 | +impl<'a> Hints<'a> { |
| 12 | + pub fn new(values: HintSet<'a>, discriminator: HintSet<'a>) -> Self { |
| 13 | + Hints { |
| 14 | + values, |
| 15 | + discriminator, |
| 16 | + } |
| 17 | + } |
| 18 | + |
| 19 | + fn sub_hints(&self, key: &str) -> Self { |
| 20 | + Self::new( |
| 21 | + self.values.sub_hints(key), |
| 22 | + self.discriminator.sub_hints(key), |
| 23 | + ) |
| 24 | + } |
| 25 | + |
| 26 | + fn is_values_active(&self) -> bool { |
| 27 | + self.values.is_active() |
| 28 | + } |
| 29 | + |
| 30 | + fn peek_active_discriminator(&self) -> Option<&str> { |
| 31 | + self.discriminator.peek_active() |
| 32 | + } |
| 33 | +} |
4 | 34 |
|
5 | 35 | use chrono::DateTime;
|
6 | 36 | use jtd::form::{self, TypeValue};
|
@@ -69,26 +99,42 @@ impl InferredSchema {
|
69 | 99 |
|
70 | 100 | InferredSchema::Array(Box::new(sub_infer))
|
71 | 101 | }
|
72 |
| - (InferredSchema::Unknown, Value::Object(obj)) => { |
| 102 | + (InferredSchema::Unknown, Value::Object(mut obj)) => { |
73 | 103 | if hints.is_values_active() {
|
74 | 104 | let mut sub_infer = InferredSchema::Unknown;
|
75 | 105 | for (k, v) in obj {
|
76 | 106 | sub_infer = sub_infer.infer(v, &hints.sub_hints(&k));
|
77 | 107 | }
|
78 | 108 |
|
79 |
| - InferredSchema::Values(Box::new(sub_infer)) |
80 |
| - } else { |
81 |
| - let mut props = HashMap::new(); |
82 |
| - for (k, v) in obj { |
83 |
| - let sub_infer = InferredSchema::Unknown.infer(v, &hints.sub_hints(&k)); |
84 |
| - props.insert(k, sub_infer); |
85 |
| - } |
| 109 | + return InferredSchema::Values(Box::new(sub_infer)); |
| 110 | + } |
| 111 | + |
| 112 | + if let Some(discriminator) = hints.peek_active_discriminator() { |
| 113 | + if let Some(Value::String(mapping_key)) = obj.remove(discriminator) { |
| 114 | + let infer_rest = InferredSchema::Unknown.infer(Value::Object(obj), hints); |
86 | 115 |
|
87 |
| - InferredSchema::Properties { |
88 |
| - required: props, |
89 |
| - optional: HashMap::new(), |
| 116 | + dbg!("infer rest", &discriminator, &infer_rest); |
| 117 | + |
| 118 | + let mut mapping = HashMap::new(); |
| 119 | + mapping.insert(mapping_key.to_owned(), infer_rest); |
| 120 | + |
| 121 | + return InferredSchema::Discriminator { |
| 122 | + discriminator: discriminator.to_owned(), |
| 123 | + mapping, |
| 124 | + }; |
90 | 125 | }
|
91 | 126 | }
|
| 127 | + |
| 128 | + let mut props = HashMap::new(); |
| 129 | + for (k, v) in obj { |
| 130 | + let sub_infer = InferredSchema::Unknown.infer(v, &hints.sub_hints(&k)); |
| 131 | + props.insert(k, sub_infer); |
| 132 | + } |
| 133 | + |
| 134 | + InferredSchema::Properties { |
| 135 | + required: props, |
| 136 | + optional: HashMap::new(), |
| 137 | + } |
92 | 138 | }
|
93 | 139 | (InferredSchema::Any, _) => InferredSchema::Any,
|
94 | 140 | (InferredSchema::Bool, Value::Bool(_)) => InferredSchema::Bool,
|
@@ -198,7 +244,35 @@ impl InferredSchema {
|
198 | 244 |
|
199 | 245 | return InferredSchema::Values(Box::new(sub_infer));
|
200 | 246 | }
|
201 |
| - _ => unimplemented!(), |
| 247 | + (InferredSchema::Values(_), _) => InferredSchema::Any, |
| 248 | + ( |
| 249 | + InferredSchema::Discriminator { |
| 250 | + discriminator, |
| 251 | + mut mapping, |
| 252 | + }, |
| 253 | + Value::Object(mut obj), |
| 254 | + ) => { |
| 255 | + let mapping_key = obj.remove(&discriminator); |
| 256 | + if let Some(Value::String(mapping_key_str)) = mapping_key { |
| 257 | + if !mapping.contains_key(&mapping_key_str) { |
| 258 | + mapping.insert(mapping_key_str.clone(), InferredSchema::Unknown); |
| 259 | + } |
| 260 | + |
| 261 | + let sub_infer = mapping |
| 262 | + .remove(&mapping_key_str) |
| 263 | + .unwrap() |
| 264 | + .infer(Value::Object(obj), hints); |
| 265 | + mapping.insert(mapping_key_str, sub_infer); |
| 266 | + |
| 267 | + InferredSchema::Discriminator { |
| 268 | + discriminator, |
| 269 | + mapping, |
| 270 | + } |
| 271 | + } else { |
| 272 | + InferredSchema::Any |
| 273 | + } |
| 274 | + } |
| 275 | + (InferredSchema::Discriminator { .. }, _) => InferredSchema::Any, |
202 | 276 | }
|
203 | 277 | }
|
204 | 278 |
|
|
0 commit comments