10 func SerializeValueForHash(buf *bytes.Buffer, val interface{}, schema *Schema) {
24 buf.WriteString(strconv.Itoa(val.(int)))
26 buf.WriteString(strconv.FormatFloat(val.(float64), 'g', -1, 64))
28 buf.WriteString(val.(string))
31 l := val.([]interface{})
32 for _, innerVal := range l {
33 serializeCollectionMemberForHash(buf, innerVal, schema.Elem)
38 m := val.(map[string]interface{})
41 keys = append(keys, k)
45 for _, k := range keys {
53 switch innerVal := innerVal.(type) {
55 buf.WriteString(strconv.Itoa(innerVal))
57 buf.WriteString(strconv.FormatFloat(innerVal, 'g', -1, 64))
59 buf.WriteString(innerVal)
61 panic(fmt.Sprintf("unknown value type in TypeMap %T", innerVal))
70 for _, innerVal := range s.List() {
71 serializeCollectionMemberForHash(buf, innerVal, schema.Elem)
75 panic("unknown schema type to serialize")
80 // SerializeValueForHash appends a serialization of the given resource config
81 // to the given buffer, guaranteeing deterministic results given the same value
84 // Its primary purpose is as input into a hashing function in order
85 // to hash complex substructures when used in sets, and so the serialization
87 func SerializeResourceForHash(buf *bytes.Buffer, val interface{}, resource *Resource) {
92 m := val.(map[string]interface{})
95 keys = append(keys, k)
98 for _, k := range keys {
100 // Skip attributes that are not user-provided. Computed attributes
101 // do not contribute to the hash since their ultimate value cannot
102 // be known at plan/diff time.
103 if !(innerSchema.Required || innerSchema.Optional) {
110 SerializeValueForHash(buf, innerVal, innerSchema)
114 func serializeCollectionMemberForHash(buf *bytes.Buffer, val interface{}, elem interface{}) {
115 switch tElem := elem.(type) {
117 SerializeValueForHash(buf, val, tElem)
120 SerializeResourceForHash(buf, val, tElem)
121 buf.WriteString(">;")
123 panic(fmt.Sprintf("invalid element type: %T", tElem))