@@ -39,7 +39,8 @@ func Marshal(model any, isUpdate bool) ([]byte, error) {
39
39
}
40
40
41
41
// Unmarshal gets a JSON (e.g. from an Atlas response) and unmarshals it into a Terraform model.
42
- // It supports the following Terraform model types: String, Bool, Int64, Float64.
42
+ // It supports the following Terraform model types: String, Bool, Int64, Float64, Object, List, Set.
43
+ // Map is not supported yet as it is not used in the Atlas API.
43
44
// Attributes that are in JSON but not in the model are ignored, no error is returned.
44
45
// Object attributes that are unknown are converted to null as all values must be known in the response state.
45
46
func Unmarshal (raw []byte , model any ) error {
@@ -192,6 +193,22 @@ func unmarshalAttr(attrNameJSON string, attrObjJSON any, valModel reflect.Value)
192
193
return err
193
194
}
194
195
return setAttrTfModel (attrNameModel , fieldModel , objNew )
196
+ case []any :
197
+ switch collection := fieldModel .Interface ().(type ) {
198
+ case types.List :
199
+ list , err := setListAttrModel (collection , v )
200
+ if err != nil {
201
+ return err
202
+ }
203
+ return setAttrTfModel (attrNameModel , fieldModel , list )
204
+ case types.Set :
205
+ set , err := setSetAttrModel (collection , v )
206
+ if err != nil {
207
+ return err
208
+ }
209
+ return setAttrTfModel (attrNameModel , fieldModel , set )
210
+ }
211
+ return fmt .Errorf ("unmarshal expects collection for field %s" , attrNameJSON )
195
212
default :
196
213
return fmt .Errorf ("unmarshal not supported yet for type %T for field %s" , v , attrNameJSON )
197
214
}
@@ -270,6 +287,45 @@ func setObjAttrModel(obj types.Object, objJSON map[string]any) (attr.Value, erro
270
287
return objNew , nil
271
288
}
272
289
290
+ func setListAttrModel (list types.List , arrayJSON []any ) (attr.Value , error ) {
291
+ elmType := list .ElementType (context .Background ())
292
+ elms , err := getCollectionElements (arrayJSON , elmType )
293
+ if err != nil {
294
+ return nil , err
295
+ }
296
+ listNew , diags := types .ListValue (elmType , elms )
297
+ if diags .HasError () {
298
+ return nil , fmt .Errorf ("unmarshal failed to convert list to object: %v" , diags )
299
+ }
300
+ return listNew , nil
301
+ }
302
+
303
+ func setSetAttrModel (set types.Set , arrayJSON []any ) (attr.Value , error ) {
304
+ elmType := set .ElementType (context .Background ())
305
+ elms , err := getCollectionElements (arrayJSON , elmType )
306
+ if err != nil {
307
+ return nil , err
308
+ }
309
+ setNew , diags := types .SetValue (elmType , elms )
310
+ if diags .HasError () {
311
+ return nil , fmt .Errorf ("unmarshal failed to convert set to object: %v" , diags )
312
+ }
313
+ return setNew , nil
314
+ }
315
+
316
+ func getCollectionElements (arrayJSON []any , _ attr.Type ) ([]attr.Value , error ) {
317
+ elms := make ([]attr.Value , len (arrayJSON ))
318
+ for i , item := range arrayJSON {
319
+ switch v := item .(type ) {
320
+ case string :
321
+ elms [i ] = types .StringValue (v )
322
+ default :
323
+ return nil , fmt .Errorf ("unmarshal not supported yet for type %T in list" , v )
324
+ }
325
+ }
326
+ return elms , nil
327
+ }
328
+
273
329
func getObjAttrsAndTypes (obj types.Object ) (mapAttrs map [string ]attr.Value , mapTypes map [string ]attr.Type , err error ) {
274
330
// mapTypes has all attributes, mapAttrs might not have them, e.g. in null or unknown objects
275
331
mapAttrs = obj .Attributes ()
0 commit comments