func attrValueFromJSON()

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)
	}
}