in internal/services/dynamic/dynamic.go [128:283]
func attrValueFromJSON(b []byte, typ attr.Type) (attr.Value, error) {
switch typ := typ.(type) {
case basetypes.BoolType:
if b == nil || string(b) == "null" {
return types.BoolNull(), nil
}
var v bool
if err := json.Unmarshal(b, &v); err != nil {
return nil, err
}
return types.BoolValue(v), nil
case basetypes.StringType:
if b == nil || string(b) == "null" {
return types.StringNull(), nil
}
var v string
if err := json.Unmarshal(b, &v); err != nil {
return nil, err
}
return types.StringValue(v), nil
case basetypes.Int64Type:
if b == nil || string(b) == "null" {
return types.Int64Null(), nil
}
var v int64
if err := json.Unmarshal(b, &v); err != nil {
return nil, err
}
return types.Int64Value(v), nil
case basetypes.Float64Type:
if b == nil || string(b) == "null" {
return types.Float64Null(), nil
}
var v float64
if err := json.Unmarshal(b, &v); err != nil {
return nil, err
}
return types.Float64Value(v), nil
case basetypes.NumberType:
if b == nil || string(b) == "null" {
return types.NumberNull(), nil
}
var v float64
if err := json.Unmarshal(b, &v); err != nil {
return nil, err
}
return types.NumberValue(big.NewFloat(v)), nil
case basetypes.ListType:
if b == nil || string(b) == "null" {
return types.ListNull(typ.ElemType), nil
}
vals, err := attrListFromJSON(b, typ.ElemType)
if err != nil {
return nil, err
}
vv, diags := types.ListValue(typ.ElemType, vals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return vv, nil
case basetypes.SetType:
if b == nil || string(b) == "null" {
return types.SetNull(typ.ElemType), nil
}
vals, err := attrListFromJSON(b, typ.ElemType)
if err != nil {
return nil, err
}
vv, diags := types.SetValue(typ.ElemType, vals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return vv, nil
case basetypes.TupleType:
if b == nil || string(b) == "null" {
return types.TupleNull(typ.ElemTypes), nil
}
var l []json.RawMessage
if err := json.Unmarshal(b, &l); err != nil {
return nil, err
}
if len(l) != len(typ.ElemTypes) {
return nil, fmt.Errorf("tuple element size not match: json=%d, type=%d", len(l), len(typ.ElemTypes))
}
vals := make([]attr.Value, 0)
for i, b := range l {
val, err := attrValueFromJSON(b, typ.ElemTypes[i])
if err != nil {
return nil, err
}
vals = append(vals, val)
}
vv, diags := types.TupleValue(typ.ElemTypes, vals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return vv, nil
case basetypes.MapType:
if b == nil || string(b) == "null" {
return types.MapNull(typ.ElemType), nil
}
var m map[string]json.RawMessage
if err := json.Unmarshal(b, &m); err != nil {
return nil, err
}
vals := map[string]attr.Value{}
for k, v := range m {
val, err := attrValueFromJSON(v, typ.ElemType)
if err != nil {
return nil, err
}
vals[k] = val
}
vv, diags := types.MapValue(typ.ElemType, vals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return vv, nil
case basetypes.ObjectType:
if b == nil || string(b) == "null" {
return types.ObjectNull(typ.AttributeTypes()), nil
}
var m map[string]json.RawMessage
if err := json.Unmarshal(b, &m); err != nil {
return nil, err
}
vals := map[string]attr.Value{}
attrTypes := typ.AttributeTypes()
for k, attrType := range attrTypes {
val, err := attrValueFromJSON(m[k], attrType)
if err != nil {
return nil, err
}
vals[k] = val
}
vv, diags := types.ObjectValue(attrTypes, vals)
if diags.HasError() {
diag := diags.Errors()[0]
return nil, fmt.Errorf("%s: %s", diag.Summary(), diag.Detail())
}
return vv, nil
case basetypes.DynamicType:
if b == nil || string(b) == "null" {
return types.DynamicNull(), nil
}
_, vv, err := attrValueFromJSONImplied(b)
return vv, err
default:
return nil, fmt.Errorf("Unhandled type: %T", typ)
}
}