44use chrono:: { DateTime , Local } ;
55use rust_i18n:: t;
66use schemars:: JsonSchema ;
7- use serde:: { Deserialize , Deserializer , Serialize } ;
7+ use serde:: { Deserialize , Serialize } ;
88use serde_json:: { Map , Value } ;
99use std:: { collections:: HashMap , fmt:: Display } ;
1010
@@ -181,11 +181,6 @@ pub struct Configuration {
181181 #[ serde( rename = "$schema" ) ]
182182 #[ schemars( schema_with = "Configuration::recognized_schema_uris_subschema" ) ]
183183 pub schema : String ,
184- /// Irrelevant Bicep metadata from using the extension
185- /// TODO: Potentially check this as a feature flag.
186- #[ serde( skip_serializing_if = "Option::is_none" ) ]
187- #[ serde( rename = "languageVersion" ) ]
188- pub language_version : Option < String > ,
189184 #[ serde( rename = "contentVersion" ) ]
190185 pub content_version : Option < String > ,
191186 #[ serde( skip_serializing_if = "Option::is_none" ) ]
@@ -196,53 +191,9 @@ pub struct Configuration {
196191 pub outputs : Option < HashMap < String , Output > > ,
197192 #[ serde( skip_serializing_if = "Option::is_none" ) ]
198193 pub parameters : Option < HashMap < String , Parameter > > ,
199- #[ serde( deserialize_with = "deserialize_resources" ) ]
200194 pub resources : Vec < Resource > ,
201195 #[ serde( skip_serializing_if = "Option::is_none" ) ]
202196 pub variables : Option < Map < String , Value > > ,
203- /// Irrelevant Bicep metadata from using the extension
204- #[ serde( skip_serializing_if = "Option::is_none" ) ]
205- pub imports : Option < Map < String , Value > > ,
206- #[ serde( skip_serializing_if = "Option::is_none" ) ]
207- pub extensions : Option < Map < String , Value > > ,
208- }
209-
210- /// Simplest implementation of a custom deserializer that will map a JSON object
211- /// of resources (where the keys are symbolic names) as found in ARMv2 back to a
212- /// vector, so the rest of this codebase can remain untouched.
213- fn deserialize_resources < ' de , D > ( deserializer : D ) -> Result < Vec < Resource > , D :: Error >
214- where
215- D : Deserializer < ' de > ,
216- {
217- let value = Value :: deserialize ( deserializer) ?;
218-
219- match value {
220- Value :: Array ( resources) => {
221- resources. into_iter ( )
222- . map ( |resource| serde_json:: from_value :: < Resource > ( resource) . map_err ( serde:: de:: Error :: custom) )
223- . collect ( )
224- }
225- Value :: Object ( resources) => {
226- resources. into_iter ( )
227- . map ( |( name, resource) | {
228- let mut resource = serde_json:: from_value :: < Resource > ( resource) . map_err ( serde:: de:: Error :: custom) ?;
229- // Note that this is setting the symbolic name as the
230- // resource's name property only if that isn't already set.
231- // In the general use case from Bicep, it won't be, but
232- // we're unsure of the implications in other use cases.
233- //
234- // TODO: We will need to update the 'dependsOn' logic to
235- // accept both the symbolic name as mapped here in addition
236- // to `resourceId()`, or possibly track both.
237- if resource. name . is_empty ( ) {
238- resource. name = name;
239- }
240- Ok ( resource)
241- } )
242- . collect ( )
243- }
244- other => Err ( serde:: de:: Error :: custom ( format ! ( "Expected resources to be either an array or an object, but was {:?}" , other) ) ) ,
245- }
246197}
247198
248199#[ derive( Debug , Clone , PartialEq , Deserialize , Serialize , JsonSchema , DscRepoSchema ) ]
@@ -419,11 +370,6 @@ pub struct Resource {
419370 pub resources : Option < Vec < Resource > > ,
420371 #[ serde( skip_serializing_if = "Option::is_none" ) ]
421372 pub metadata : Option < Metadata > ,
422- /// Irrelevant Bicep metadata from using the extension
423- #[ serde( skip_serializing_if = "Option::is_none" ) ]
424- pub import : Option < String > ,
425- #[ serde( skip_serializing_if = "Option::is_none" ) ]
426- pub extension : Option < String > ,
427373}
428374
429375impl Default for Configuration {
@@ -437,16 +383,13 @@ impl Configuration {
437383 pub fn new ( ) -> Self {
438384 Self {
439385 schema : Self :: default_schema_id_uri ( ) ,
440- language_version : None ,
441386 content_version : Some ( "1.0.0" . to_string ( ) ) ,
442387 metadata : None ,
443388 parameters : None ,
444389 resources : Vec :: new ( ) ,
445390 functions : None ,
446391 variables : None ,
447392 outputs : None ,
448- imports : None ,
449- extensions : None ,
450393 }
451394 }
452395}
@@ -472,8 +415,6 @@ impl Resource {
472415 location : None ,
473416 tags : None ,
474417 api_version : None ,
475- import : None ,
476- extension : None ,
477418 }
478419 }
479420}
@@ -539,22 +480,6 @@ mod test {
539480 assert ! ( err. starts_with( "unknown field `invalidField`, expected one of `condition`, `type`," ) ) ;
540481 }
541482
542- #[ test]
543- fn test_invalid_resource_field_in_object ( ) {
544- let config_json = r#"{
545- "resources": {
546- "someResource": {
547- "invalidField": "someValue"
548- }
549- }
550- }"# ;
551-
552- let result: Result < Configuration , _ > = serde_json:: from_str ( config_json) ;
553- assert ! ( result. is_err( ) ) ;
554- let err = result. unwrap_err ( ) . to_string ( ) ;
555- assert ! ( err. starts_with( "unknown field `invalidField`, expected one of `condition`, `type`," ) ) ;
556- }
557-
558483 #[ test]
559484 fn test_invalid_resource_type_in_array ( ) {
560485 let config_json = r#"{
@@ -569,20 +494,6 @@ mod test {
569494 assert ! ( err. contains( "expected struct Resource" ) ) ;
570495 }
571496
572- #[ test]
573- fn test_invalid_resource_type_in_object ( ) {
574- let config_json = r#"{
575- "resources": {
576- "someResource": "invalidType"
577- }
578- }"# ;
579-
580- let result: Result < Configuration , _ > = serde_json:: from_str ( config_json) ;
581- assert ! ( result. is_err( ) ) ;
582- let err = result. unwrap_err ( ) . to_string ( ) ;
583- assert ! ( err. contains( "expected struct Resource" ) ) ;
584- }
585-
586497 #[ test]
587498 fn test_resources_as_array ( ) {
588499 let config_json = r#"{
@@ -613,49 +524,4 @@ mod test {
613524 assert_eq ! ( config. resources[ 1 ] . api_version. as_deref( ) , Some ( "0.1.0" ) ) ;
614525 }
615526
616- #[ test]
617- fn test_resources_with_symbolic_names ( ) {
618- let config_json = r#"{
619- "$schema": "https://aka.ms/dsc/schemas/v3/bundled/config/document.json",
620- "languageVersion": "2.2-experimental",
621- "extensions": {
622- "dsc": {
623- "name": "DesiredStateConfiguration",
624- "version": "0.1.0"
625- }
626- },
627- "resources": {
628- "echoResource": {
629- "extension": "dsc",
630- "type": "Microsoft.DSC.Debug/Echo",
631- "apiVersion": "1.0.0",
632- "properties": {
633- "output": "Hello World"
634- }
635- },
636- "processResource": {
637- "extension": "dsc",
638- "type": "Microsoft/Process",
639- "apiVersion": "0.1.0",
640- "properties": {
641- "name": "pwsh",
642- "pid": 1234
643- }
644- }
645- }
646- }"# ;
647-
648- let config: Configuration = serde_json:: from_str ( config_json) . unwrap ( ) ;
649- assert_eq ! ( config. resources. len( ) , 2 ) ;
650-
651- // Find resources by name (order may vary in HashMap)
652- let echo_resource = config. resources . iter ( ) . find ( |r| r. name == "echoResource" ) . unwrap ( ) ;
653- let process_resource = config. resources . iter ( ) . find ( |r| r. name == "processResource" ) . unwrap ( ) ;
654-
655- assert_eq ! ( echo_resource. resource_type, "Microsoft.DSC.Debug/Echo" ) ;
656- assert_eq ! ( echo_resource. api_version. as_deref( ) , Some ( "1.0.0" ) ) ;
657-
658- assert_eq ! ( process_resource. resource_type, "Microsoft/Process" ) ;
659- assert_eq ! ( process_resource. api_version. as_deref( ) , Some ( "0.1.0" ) ) ;
660- }
661527}
0 commit comments