in internal/services/dynamic/dynamic.go [302:368]
func attrValueFromJSONImplied(b []byte) (attr.Type, attr.Value, error) {
if string(b) == "null" {
return types.DynamicType, types.DynamicNull(), nil
}
if string(b) == "<unknown>" {
return types.DynamicType, types.DynamicUnknown(), nil
}
var object map[string]json.RawMessage
if err := json.Unmarshal(b, &object); err == nil {
attrTypes := map[string]attr.Type{}
attrVals := map[string]attr.Value{}
for k, v := range object {
attrTypes[k], attrVals[k], err = attrValueFromJSONImplied(v)
if err != nil {
return nil, nil, err
}
}
typ := types.ObjectType{AttrTypes: attrTypes}
val, diags := types.ObjectValue(attrTypes, attrVals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return typ, val, nil
}
var array []json.RawMessage
if err := json.Unmarshal(b, &array); err == nil {
eTypes := []attr.Type{}
eVals := []attr.Value{}
for _, e := range array {
eType, eVal, err := attrValueFromJSONImplied(e)
if err != nil {
return nil, nil, err
}
eTypes = append(eTypes, eType)
eVals = append(eVals, eVal)
}
typ := types.TupleType{ElemTypes: eTypes}
val, diags := types.TupleValue(eTypes, eVals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return typ, val, nil
}
// Primitives
var v interface{}
if err := json.Unmarshal(b, &v); err != nil {
return nil, nil, fmt.Errorf("failed to unmarshal %s: %v", string(b), err)
}
switch v := v.(type) {
case bool:
return types.BoolType, types.BoolValue(v), nil
case float64:
return types.NumberType, types.NumberValue(big.NewFloat(v)), nil
case string:
return types.StringType, types.StringValue(v), nil
case nil:
return types.DynamicType, types.DynamicNull(), nil
default:
return nil, nil, fmt.Errorf("Unhandled type: %T", v)
}
}