govendor fetch github.com/zclconf/go-cty/...

This commit is contained in:
Martin Atkins
2018-03-16 16:59:02 -07:00
parent a79d620f03
commit b41f08d79d
4 changed files with 98 additions and 18 deletions

View File

@@ -19,12 +19,24 @@ type setRules struct {
Type Type
}
// Hash returns a hash value for the receiver that can be used for equality
// checks where some inaccuracy is tolerable.
//
// The hash function is value-type-specific, so it is not meaningful to compare
// hash results for values of different types.
//
// This function is not safe to use for security-related applications, since
// the hash used is not strong enough.
func (val Value) Hash() int {
hashBytes := makeSetHashBytes(val)
return int(crc32.ChecksumIEEE(hashBytes))
}
func (r setRules) Hash(v interface{}) int {
hashBytes := makeSetHashBytes(Value{
return Value{
ty: r.Type,
v: v,
})
return int(crc32.ChecksumIEEE(hashBytes))
}.Hash()
}
func (r setRules) Equivalent(v1 interface{}, v2 interface{}) bool {

View File

@@ -0,0 +1,64 @@
package cty
// UnknownAsNull returns a value of the same type as the given value but
// with any unknown values (including nested values) replaced with null
// values of the same type.
//
// This can be useful if a result is to be serialized in a format that can't
// represent unknowns, such as JSON, as long as the caller does not need to
// retain the unknown value information.
func UnknownAsNull(val Value) Value {
if !val.IsKnown() {
return NullVal(val.Type())
}
ty := val.Type()
switch {
case ty.IsListType() || ty.IsTupleType() || ty.IsSetType():
length := val.LengthInt()
if length == 0 {
// If there are no elements then we can't have unknowns
return val
}
vals := make([]Value, 0, length)
it := val.ElementIterator()
for it.Next() {
_, v := it.Element()
vals = append(vals, UnknownAsNull(v))
}
switch {
case ty.IsListType():
return ListVal(vals)
case ty.IsTupleType():
return TupleVal(vals)
default:
return SetVal(vals)
}
case ty.IsMapType() || ty.IsObjectType():
var length int
switch {
case ty.IsMapType():
length = val.LengthInt()
default:
length = len(val.Type().AttributeTypes())
}
if length == 0 {
// If there are no elements then we can't have unknowns
return val
}
vals := make(map[string]Value, length)
it := val.ElementIterator()
for it.Next() {
k, v := it.Element()
vals[k.AsString()] = UnknownAsNull(v)
}
switch {
case ty.IsMapType():
return MapVal(vals)
default:
return ObjectVal(vals)
}
}
return val
}

View File

@@ -800,6 +800,10 @@ func (val Value) LengthInt() int {
// For tuples, we can return the length even if the value is not known.
return val.Type().Length()
}
if val.Type().IsObjectType() {
// For objects, the length is the number of attributes associated with the type.
return len(val.Type().AttributeTypes())
}
if !val.IsKnown() {
panic("value is not known")
}