diff --git a/crates/assemble/src/lib.rs b/crates/assemble/src/lib.rs index 57e060164e..7a9d2d4a5c 100644 --- a/crates/assemble/src/lib.rs +++ b/crates/assemble/src/lib.rs @@ -63,7 +63,22 @@ pub fn inference(shape: &Shape, exists: Exists) -> flow::Inference { } else { None }, - array: None, + array: if shape.type_.overlaps(types::ARRAY) { + Some(flow::inference::Array { + min_items: shape.array.min_items, + has_max_items: shape.array.max_items.is_some(), + max_items: shape.array.max_items.unwrap_or_default(), + item_types: shape + .array + .tuple + .iter() + .chain(shape.array.additional_items.as_deref()) + .fold(types::INVALID, |acc, item| acc | item.type_) + .to_vec(), + }) + } else { + None + }, } } @@ -484,7 +499,7 @@ pub fn pb_datetime(t: &time::OffsetDateTime) -> pbjson_types::Timestamp { #[cfg(test)] mod test { use super::*; - use doc::shape::{NumericShape, StringShape}; + use doc::shape::{ArrayShape, NumericShape, StringShape}; use serde_json::{json, Value}; use std::collections::BTreeMap; @@ -507,6 +522,28 @@ mod test { minimum: None, maximum: Some(json::Number::Unsigned(1000)), }, + array: ArrayShape { + additional_items: Some(Box::new(Shape { + type_: types::STRING, + ..Shape::anything() + })), + min_items: 10, + max_items: Some(20), + tuple: vec![ + Shape { + type_: types::STRING, + ..Shape::anything() + }, + Shape { + type_: types::BOOLEAN, + ..Shape::anything() + }, + Shape { + type_: types::OBJECT, + ..Shape::anything() + }, + ], + }, ..Shape::anything() }; @@ -515,8 +552,10 @@ mod test { let out2 = inference(&shape, Exists::May); shape.type_ = types::INTEGER | types::STRING; let out3 = inference(&shape, Exists::May); + shape.type_ = types::ARRAY; + let out4 = inference(&shape, Exists::May); - insta::assert_debug_snapshot!(&[out1, out2, out3]); + insta::assert_debug_snapshot!(&[out1, out2, out3, out4]); } #[test] diff --git a/crates/assemble/src/snapshots/assemble__test__inference.snap b/crates/assemble/src/snapshots/assemble__test__inference.snap index 54836fa844..0853f34ac1 100644 --- a/crates/assemble/src/snapshots/assemble__test__inference.snap +++ b/crates/assemble/src/snapshots/assemble__test__inference.snap @@ -1,6 +1,6 @@ --- source: crates/assemble/src/lib.rs -expression: "&[out1, out2, out3]" +expression: "&[out1, out2, out3, out4]" --- [ Inference { @@ -65,4 +65,28 @@ expression: "&[out1, out2, out3]" ), array: None, }, + Inference { + types: [ + "array", + ], + string: None, + title: "the title", + description: "the description", + default_json: "{\"hello\":\"world\"}", + secret: true, + exists: May, + numeric: None, + array: Some( + Array { + min_items: 10, + has_max_items: true, + max_items: 20, + item_types: [ + "boolean", + "object", + "string", + ], + }, + ), + }, ] diff --git a/crates/validation/tests/snapshots/scenario_tests__golden_all_visits.snap b/crates/validation/tests/snapshots/scenario_tests__golden_all_visits.snap index 16905e4bec..7d3a394340 100644 --- a/crates/validation/tests/snapshots/scenario_tests__golden_all_visits.snap +++ b/crates/validation/tests/snapshots/scenario_tests__golden_all_visits.snap @@ -1271,7 +1271,16 @@ Outcome { secret: false, exists: Must, numeric: None, - array: None, + array: Some( + Array { + min_items: 5, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -1740,7 +1749,16 @@ Outcome { secret: false, exists: Must, numeric: None, - array: None, + array: Some( + Array { + min_items: 5, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -2001,7 +2019,16 @@ Outcome { secret: false, exists: Must, numeric: None, - array: None, + array: Some( + Array { + min_items: 5, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -2550,7 +2577,16 @@ Outcome { secret: false, exists: May, numeric: None, - array: None, + array: Some( + Array { + min_items: 0, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -2927,7 +2963,16 @@ Outcome { secret: false, exists: May, numeric: None, - array: None, + array: Some( + Array { + min_items: 0, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -3390,7 +3435,16 @@ Outcome { secret: false, exists: May, numeric: None, - array: None, + array: Some( + Array { + min_items: 0, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -5180,7 +5234,16 @@ Outcome { secret: false, exists: May, numeric: None, - array: None, + array: Some( + Array { + min_items: 0, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), }, @@ -6750,7 +6813,16 @@ Outcome { secret: false, exists: May, numeric: None, - array: None, + array: Some( + Array { + min_items: 0, + has_max_items: false, + max_items: 0, + item_types: [ + "object", + ], + }, + ), }, ), },