@@ -26,9 +26,6 @@ pub enum Error {
2626 source : serde_json:: Error ,
2727 index : usize ,
2828 } ,
29-
30- #[ snafu( display( "failed to parse user-provided JSON content" ) ) ]
31- ParseUserProvidedJson { source : serde_json:: Error } ,
3229}
3330
3431/// Trait that allows the product config pipeline to extract flat key-value
@@ -89,8 +86,33 @@ pub enum JsonConfigOverrides {
8986 /// `{"op": "add", "path": "/0/happy", "value": true}`
9087 JsonPatches ( Vec < String > ) ,
9188
92- /// Override the entire config file with the specified String.
93- UserProvided ( String ) ,
89+ /// Override the entire config file with the specified JSON document.
90+ ///
91+ /// Please note that you can in-line JSON into YAML as follows:
92+ ///
93+ /// ```yaml
94+ /// # ... other YAML content
95+ /// userProvided: {
96+ /// "myString": "test",
97+ /// "myList": ["test"],
98+ /// "myBool": true,
99+ /// "my": {"nested.field.with.dots": 42}
100+ /// }
101+ /// ```
102+ ///
103+ /// As an alternative you can also stick to YAML:
104+ ///
105+ /// ```yaml
106+ /// # ... other YAML content
107+ /// userProvided:
108+ /// myString: test
109+ /// myList: [test]
110+ /// myBool: true
111+ /// my:
112+ /// nested.field.with.dots: 42
113+ /// ```
114+ #[ schemars( schema_with = "raw_object_schema" ) ]
115+ UserProvided ( serde_json:: Value ) ,
94116}
95117
96118impl JsonConfigOverrides {
@@ -123,18 +145,18 @@ impl JsonConfigOverrides {
123145 json_patch:: patch ( & mut doc, & operations) . context ( ApplyJsonPatchSnafu ) ?;
124146 Ok ( doc)
125147 }
126- Self :: UserProvided ( content) => {
127- serde_json:: from_str ( content) . context ( ParseUserProvidedJsonSnafu )
128- }
148+ Self :: UserProvided ( content) => Ok ( content. clone ( ) ) ,
129149 }
130150 }
131151}
132152
133153#[ cfg( test) ]
134154mod tests {
155+ use rstest:: rstest;
135156 use serde_json:: json;
136157
137158 use super :: * ;
159+ use crate :: utils:: yaml_from_str_singleton_map;
138160
139161 #[ test]
140162 fn json_merge_patch_add_and_overwrite_fields ( ) {
@@ -244,30 +266,16 @@ mod tests {
244266 #[ test]
245267 fn user_provided_ignores_base ( ) {
246268 let base = json ! ( { "foo" : "bar" } ) ;
247- let content = "{ \ " custom\ " : true}" ;
269+ let content = json ! ( { "custom" : true } ) ;
248270
249- let overrides = JsonConfigOverrides :: UserProvided ( content. to_owned ( ) ) ;
271+ let overrides = JsonConfigOverrides :: UserProvided ( content) ;
250272
251273 let result = overrides
252274 . apply ( & base)
253275 . expect ( "user provided should succeed" ) ;
254276 assert_eq ! ( result, json!( { "custom" : true } ) ) ;
255277 }
256278
257- #[ test]
258- fn user_provided_invalid_json_returns_error ( ) {
259- let base = json ! ( { "foo" : "bar" } ) ;
260-
261- let overrides = JsonConfigOverrides :: UserProvided ( "not valid json" . to_owned ( ) ) ;
262-
263- let result = overrides. apply ( & base) ;
264- assert ! (
265- matches!( result. unwrap_err( ) , Error :: ParseUserProvidedJson { source } if source. to_string( )
266- == "expected ident at line 1 column 2" ) ,
267- "invalid JSON should return an error"
268- ) ;
269- }
270-
271279 #[ test]
272280 fn key_value_config_overrides_as_product_config_overrides ( ) {
273281 let mut overrides = BTreeMap :: new ( ) ;
@@ -281,4 +289,43 @@ mod tests {
281289 assert_eq ! ( result. get( "key1" ) , Some ( & Some ( "value1" . to_owned( ) ) ) ) ;
282290 assert_eq ! ( result. get( "key2" ) , Some ( & Some ( "value2" . to_owned( ) ) ) ) ;
283291 }
292+
293+ #[ rstest]
294+ #[ case:: inline_json(
295+ r#"
296+ # ... other YAML content
297+ userProvided: {
298+ "myString": "test",
299+ "myList": ["test"],
300+ "myBool": true,
301+ "my": {"nested.field.with.dots": 42}
302+ }
303+ "#
304+ ) ]
305+ #[ case:: inline_yaml(
306+ "
307+ # ... other YAML content
308+ userProvided:
309+ myString: test
310+ myList: [test]
311+ myBool: true
312+ my:
313+ nested.field.with.dots: 42
314+ "
315+ ) ]
316+ fn parse_user_provided_json ( #[ case] yaml : String ) {
317+ let expected = json ! ( {
318+ "myString" : "test" ,
319+ "myList" : [ "test" ] ,
320+ "myBool" : true ,
321+ "my" : { "nested.field.with.dots" : 42 }
322+ } ) ;
323+ let json_config_overrides: JsonConfigOverrides =
324+ yaml_from_str_singleton_map ( & yaml) . unwrap ( ) ;
325+
326+ match json_config_overrides {
327+ JsonConfigOverrides :: UserProvided ( value) => assert_eq ! ( value, expected) ,
328+ _ => panic ! ( "JsonConfigOverrides must be of type UserProvided" ) ,
329+ }
330+ }
284331}
0 commit comments