9 "github.com/zclconf/go-cty/cty/set"
12 func (val Value) GoString() string {
17 if val.ty == DynamicPseudoType {
18 return "cty.DynamicVal"
22 return fmt.Sprintf("cty.UnknownVal(%#v)", val.ty)
25 return fmt.Sprintf("cty.NullVal(%#v)", val.ty)
28 // By the time we reach here we've dealt with all of the exceptions around
29 // unknowns and nulls, so we're guaranteed that the values are the
30 // canonical internal representation of the given type.
40 fv := val.v.(*big.Float)
41 // We'll try to use NumberIntVal or NumberFloatVal if we can, since
42 // the fully-general initializer call is pretty ugly-looking.
44 return fmt.Sprintf("cty.NumberIntVal(%#v)", fv)
46 if rfv, accuracy := fv.Float64(); accuracy == big.Exact {
47 return fmt.Sprintf("cty.NumberFloatVal(%#v)", rfv)
49 return fmt.Sprintf("cty.NumberVal(new(big.Float).Parse(\"%#v\", 10))", fv)
51 return fmt.Sprintf("cty.StringVal(%#v)", val.v)
55 case val.ty.IsSetType():
56 vals := val.v.(set.Set).Values()
57 if vals == nil || len(vals) == 0 {
58 return fmt.Sprintf("cty.SetValEmpty()")
60 return fmt.Sprintf("cty.SetVal(%#v)", vals)
62 case val.ty.IsCapsuleType():
63 return fmt.Sprintf("cty.CapsuleVal(%#v, %#v)", val.ty, val.v)
66 // Default exposes implementation details, so should actually cover
67 // all of the cases above for good caller UX.
68 return fmt.Sprintf("cty.Value{ty: %#v, v: %#v}", val.ty, val.v)
71 // Equals returns True if the receiver and the given other value have the
72 // same type and are exactly equal in value.
74 // The usual short-circuit rules apply, so the result can be unknown or typed
75 // as dynamic if either of the given values are. Use RawEquals to compare
76 // if two values are equal *ignoring* the short-circuit rules.
77 func (val Value) Equals(other Value) Value {
78 if val.ty.HasDynamicTypes() || other.ty.HasDynamicTypes() {
79 return UnknownVal(Bool)
82 if !val.ty.Equals(other.ty) {
86 if !(val.IsKnown() && other.IsKnown()) {
87 return UnknownVal(Bool)
90 if val.IsNull() || other.IsNull() {
91 if val.IsNull() && other.IsNull() {
102 result = val.v.(*big.Float).Cmp(other.v.(*big.Float)) == 0
104 result = val.v.(bool) == other.v.(bool)
106 // Simple equality is safe because we NFC-normalize strings as they
107 // enter our world from StringVal, and so we can assume strings are
108 // always in normal form.
109 result = val.v.(string) == other.v.(string)
110 case ty.IsObjectType():
111 oty := ty.typeImpl.(typeObject)
113 for attr, aty := range oty.AttrTypes {
116 v: val.v.(map[string]interface{})[attr],
120 v: other.v.(map[string]interface{})[attr],
122 eq := lhs.Equals(rhs)
124 return UnknownVal(Bool)
131 case ty.IsTupleType():
132 tty := ty.typeImpl.(typeTuple)
134 for i, ety := range tty.ElemTypes {
137 v: val.v.([]interface{})[i],
141 v: other.v.([]interface{})[i],
143 eq := lhs.Equals(rhs)
145 return UnknownVal(Bool)
152 case ty.IsListType():
153 ety := ty.typeImpl.(typeList).ElementTypeT
154 if len(val.v.([]interface{})) == len(other.v.([]interface{})) {
156 for i := range val.v.([]interface{}) {
159 v: val.v.([]interface{})[i],
163 v: other.v.([]interface{})[i],
165 eq := lhs.Equals(rhs)
167 return UnknownVal(Bool)
176 s1 := val.v.(set.Set)
177 s2 := other.v.(set.Set)
180 // Note that by our definition of sets it's never possible for two
181 // sets that contain unknown values (directly or indicrectly) to
182 // ever be equal, even if they are otherwise identical.
184 // FIXME: iterating both lists and checking each item is not the
185 // ideal implementation here, but it works with the primitives we
186 // have in the set implementation. Perhaps the set implementation
187 // can provide its own equality test later.
188 s1.EachValue(func(v interface{}) {
193 s2.EachValue(func(v interface{}) {
201 ety := ty.typeImpl.(typeMap).ElementTypeT
202 if len(val.v.(map[string]interface{})) == len(other.v.(map[string]interface{})) {
204 for k := range val.v.(map[string]interface{}) {
205 if _, ok := other.v.(map[string]interface{})[k]; !ok {
211 v: val.v.(map[string]interface{})[k],
215 v: other.v.(map[string]interface{})[k],
217 eq := lhs.Equals(rhs)
219 return UnknownVal(Bool)
227 case ty.IsCapsuleType():
228 // A capsule type's encapsulated value is a pointer to a value of its
229 // native type, so we can just compare these to get the identity test
231 return BoolVal(val.v == other.v)
234 // should never happen
235 panic(fmt.Errorf("unsupported value type %#v in Equals", ty))
238 return BoolVal(result)
241 // NotEqual is a shorthand for Equals followed by Not.
242 func (val Value) NotEqual(other Value) Value {
243 return val.Equals(other).Not()
246 // True returns true if the receiver is True, false if False, and panics if
247 // the receiver is not of type Bool.
249 // This is a helper function to help write application logic that works with
250 // values, rather than a first-class operation. It does not work with unknown
251 // or null values. For more robust handling with unknown value
252 // short-circuiting, use val.Equals(cty.True).
253 func (val Value) True() bool {
257 return val.Equals(True).v.(bool)
260 // False is the opposite of True.
261 func (val Value) False() bool {
265 // RawEquals returns true if and only if the two given values have the same
266 // type and equal value, ignoring the usual short-circuit rules about
267 // unknowns and dynamic types.
269 // This method is more appropriate for testing than for real use, since it
270 // skips over usual semantics around unknowns but as a consequence allows
271 // testing the result of another operation that is expected to return unknown.
272 // It returns a primitive Go bool rather than a Value to remind us that it
273 // is not a first-class value operation.
274 func (val Value) RawEquals(other Value) bool {
275 if !val.ty.Equals(other.ty) {
278 if (!val.IsKnown()) && (!other.IsKnown()) {
281 if (val.IsKnown() && !other.IsKnown()) || (other.IsKnown() && !val.IsKnown()) {
284 if val.IsNull() && other.IsNull() {
287 if (val.IsNull() && !other.IsNull()) || (other.IsNull() && !val.IsNull()) {
290 if val.ty == DynamicPseudoType && other.ty == DynamicPseudoType {
296 case ty == Number || ty == Bool || ty == String || ty == DynamicPseudoType:
297 return val.Equals(other).True()
298 case ty.IsObjectType():
299 oty := ty.typeImpl.(typeObject)
300 for attr, aty := range oty.AttrTypes {
303 v: val.v.(map[string]interface{})[attr],
307 v: other.v.(map[string]interface{})[attr],
309 eq := lhs.RawEquals(rhs)
315 case ty.IsTupleType():
316 tty := ty.typeImpl.(typeTuple)
317 for i, ety := range tty.ElemTypes {
320 v: val.v.([]interface{})[i],
324 v: other.v.([]interface{})[i],
326 eq := lhs.RawEquals(rhs)
332 case ty.IsListType():
333 ety := ty.typeImpl.(typeList).ElementTypeT
334 if len(val.v.([]interface{})) == len(other.v.([]interface{})) {
335 for i := range val.v.([]interface{}) {
338 v: val.v.([]interface{})[i],
342 v: other.v.([]interface{})[i],
344 eq := lhs.RawEquals(rhs)
353 s1 := val.v.(set.Set)
354 s2 := other.v.(set.Set)
356 // Since we're intentionally ignoring our rule that two unknowns
357 // are never equal, we can cheat here.
358 // (This isn't 100% right since e.g. it will fail if the set contains
359 // numbers that are infinite, which DeepEqual can't compare properly.
360 // We're accepting that limitation for simplicity here, since this
361 // function is here primarily for testing.)
362 return reflect.DeepEqual(s1, s2)
365 ety := ty.typeImpl.(typeMap).ElementTypeT
366 if len(val.v.(map[string]interface{})) == len(other.v.(map[string]interface{})) {
367 for k := range val.v.(map[string]interface{}) {
368 if _, ok := other.v.(map[string]interface{})[k]; !ok {
373 v: val.v.(map[string]interface{})[k],
377 v: other.v.(map[string]interface{})[k],
379 eq := lhs.RawEquals(rhs)
387 case ty.IsCapsuleType():
388 // A capsule type's encapsulated value is a pointer to a value of its
389 // native type, so we can just compare these to get the identity test
391 return val.v == other.v
394 // should never happen
395 panic(fmt.Errorf("unsupported value type %#v in RawEquals", ty))
399 // Add returns the sum of the receiver and the given other value. Both values
400 // must be numbers; this method will panic if not.
401 func (val Value) Add(other Value) Value {
402 if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
403 shortCircuit = forceShortCircuitType(shortCircuit, Number)
407 ret := new(big.Float)
408 ret.Add(val.v.(*big.Float), other.v.(*big.Float))
409 return NumberVal(ret)
412 // Subtract returns receiver minus the given other value. Both values must be
413 // numbers; this method will panic if not.
414 func (val Value) Subtract(other Value) Value {
415 if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
416 shortCircuit = forceShortCircuitType(shortCircuit, Number)
420 return val.Add(other.Negate())
423 // Negate returns the numeric negative of the receiver, which must be a number.
424 // This method will panic when given a value of any other type.
425 func (val Value) Negate() Value {
426 if shortCircuit := mustTypeCheck(Number, Number, val); shortCircuit != nil {
427 shortCircuit = forceShortCircuitType(shortCircuit, Number)
431 ret := new(big.Float).Neg(val.v.(*big.Float))
432 return NumberVal(ret)
435 // Multiply returns the product of the receiver and the given other value.
436 // Both values must be numbers; this method will panic if not.
437 func (val Value) Multiply(other Value) Value {
438 if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
439 shortCircuit = forceShortCircuitType(shortCircuit, Number)
443 ret := new(big.Float)
444 ret.Mul(val.v.(*big.Float), other.v.(*big.Float))
445 return NumberVal(ret)
448 // Divide returns the quotient of the receiver and the given other value.
449 // Both values must be numbers; this method will panic if not.
451 // If the "other" value is exactly zero, this operation will return either
452 // PositiveInfinity or NegativeInfinity, depending on the sign of the
453 // receiver value. For some use-cases the presence of infinities may be
454 // undesirable, in which case the caller should check whether the
455 // other value equals zero before calling and raise an error instead.
457 // If both values are zero or infinity, this function will panic with
458 // an instance of big.ErrNaN.
459 func (val Value) Divide(other Value) Value {
460 if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
461 shortCircuit = forceShortCircuitType(shortCircuit, Number)
465 ret := new(big.Float)
466 ret.Quo(val.v.(*big.Float), other.v.(*big.Float))
467 return NumberVal(ret)
470 // Modulo returns the remainder of an integer division of the receiver and
471 // the given other value. Both values must be numbers; this method will panic
474 // If the "other" value is exactly zero, this operation will return either
475 // PositiveInfinity or NegativeInfinity, depending on the sign of the
476 // receiver value. For some use-cases the presence of infinities may be
477 // undesirable, in which case the caller should check whether the
478 // other value equals zero before calling and raise an error instead.
480 // This operation is primarily here for use with nonzero natural numbers.
481 // Modulo with "other" as a non-natural number gets somewhat philosophical,
482 // and this function takes a position on what that should mean, but callers
483 // may wish to disallow such things outright or implement their own modulo
484 // if they disagree with the interpretation used here.
485 func (val Value) Modulo(other Value) Value {
486 if shortCircuit := mustTypeCheck(Number, Number, val, other); shortCircuit != nil {
487 shortCircuit = forceShortCircuitType(shortCircuit, Number)
491 // We cheat a bit here with infinities, just abusing the Multiply operation
492 // to get an infinite result of the correct sign.
493 if val == PositiveInfinity || val == NegativeInfinity || other == PositiveInfinity || other == NegativeInfinity {
494 return val.Multiply(other)
497 if other.RawEquals(Zero) {
501 // FIXME: This is a bit clumsy. Should come back later and see if there's a
502 // more straightforward way to do this.
503 rat := val.Divide(other)
504 ratFloorInt := &big.Int{}
505 rat.v.(*big.Float).Int(ratFloorInt)
506 work := (&big.Float{}).SetInt(ratFloorInt)
507 work.Mul(other.v.(*big.Float), work)
508 work.Sub(val.v.(*big.Float), work)
510 return NumberVal(work)
513 // Absolute returns the absolute (signless) value of the receiver, which must
514 // be a number or this method will panic.
515 func (val Value) Absolute() Value {
516 if shortCircuit := mustTypeCheck(Number, Number, val); shortCircuit != nil {
517 shortCircuit = forceShortCircuitType(shortCircuit, Number)
521 ret := (&big.Float{}).Abs(val.v.(*big.Float))
522 return NumberVal(ret)
525 // GetAttr returns the value of the given attribute of the receiver, which
526 // must be of an object type that has an attribute of the given name.
527 // This method will panic if the receiver type is not compatible.
529 // The method will also panic if the given attribute name is not defined
530 // for the value's type. Use the attribute-related methods on Type to
531 // check for the validity of an attribute before trying to use it.
533 // This method may be called on a value whose type is DynamicPseudoType,
534 // in which case the result will also be DynamicVal.
535 func (val Value) GetAttr(name string) Value {
536 if val.ty == DynamicPseudoType {
540 if !val.ty.IsObjectType() {
541 panic("value is not an object")
544 name = NormalizeString(name)
545 if !val.ty.HasAttribute(name) {
546 panic("value has no attribute of that name")
549 attrType := val.ty.AttributeType(name)
552 return UnknownVal(attrType)
557 v: val.v.(map[string]interface{})[name],
561 // Index returns the value of an element of the receiver, which must have
562 // either a list, map or tuple type. This method will panic if the receiver
563 // type is not compatible.
565 // The key value must be the correct type for the receving collection: a
566 // number if the collection is a list or tuple, or a string if it is a map.
567 // In the case of a list or tuple, the given number must be convertable to int
568 // or this method will panic. The key may alternatively be of
569 // DynamicPseudoType, in which case the result itself is an unknown of the
570 // collection's element type.
572 // The result is of the receiver collection's element type, or in the case
573 // of a tuple the type of the specific element index requested.
575 // This method may be called on a value whose type is DynamicPseudoType,
576 // in which case the result will also be the DynamicValue.
577 func (val Value) Index(key Value) Value {
578 if val.ty == DynamicPseudoType {
583 case val.Type().IsListType():
584 elty := val.Type().ElementType()
585 if key.Type() == DynamicPseudoType {
586 return UnknownVal(elty)
589 if key.Type() != Number {
590 panic("element key for list must be number")
593 return UnknownVal(elty)
597 return UnknownVal(elty)
600 index, accuracy := key.v.(*big.Float).Int64()
601 if accuracy != big.Exact || index < 0 {
602 panic("element key for list must be non-negative integer")
607 v: val.v.([]interface{})[index],
609 case val.Type().IsMapType():
610 elty := val.Type().ElementType()
611 if key.Type() == DynamicPseudoType {
612 return UnknownVal(elty)
615 if key.Type() != String {
616 panic("element key for map must be string")
619 return UnknownVal(elty)
623 return UnknownVal(elty)
626 keyStr := key.v.(string)
630 v: val.v.(map[string]interface{})[keyStr],
632 case val.Type().IsTupleType():
633 if key.Type() == DynamicPseudoType {
637 if key.Type() != Number {
638 panic("element key for tuple must be number")
644 index, accuracy := key.v.(*big.Float).Int64()
645 if accuracy != big.Exact || index < 0 {
646 panic("element key for list must be non-negative integer")
649 eltys := val.Type().TupleElementTypes()
652 return UnknownVal(eltys[index])
657 v: val.v.([]interface{})[index],
660 panic("not a list, map, or tuple type")
664 // HasIndex returns True if the receiver (which must be supported for Index)
665 // has an element with the given index key, or False if it does not.
667 // The result will be UnknownVal(Bool) if either the collection or the
668 // key value are unknown.
670 // This method will panic if the receiver is not indexable, but does not
671 // impose any panic-causing type constraints on the key.
672 func (val Value) HasIndex(key Value) Value {
673 if val.ty == DynamicPseudoType {
674 return UnknownVal(Bool)
678 case val.Type().IsListType():
679 if key.Type() == DynamicPseudoType {
680 return UnknownVal(Bool)
683 if key.Type() != Number {
687 return UnknownVal(Bool)
690 return UnknownVal(Bool)
693 index, accuracy := key.v.(*big.Float).Int64()
694 if accuracy != big.Exact || index < 0 {
698 return BoolVal(int(index) < len(val.v.([]interface{})) && index >= 0)
699 case val.Type().IsMapType():
700 if key.Type() == DynamicPseudoType {
701 return UnknownVal(Bool)
704 if key.Type() != String {
708 return UnknownVal(Bool)
711 return UnknownVal(Bool)
714 keyStr := key.v.(string)
715 _, exists := val.v.(map[string]interface{})[keyStr]
717 return BoolVal(exists)
718 case val.Type().IsTupleType():
719 if key.Type() == DynamicPseudoType {
720 return UnknownVal(Bool)
723 if key.Type() != Number {
727 return UnknownVal(Bool)
730 index, accuracy := key.v.(*big.Float).Int64()
731 if accuracy != big.Exact || index < 0 {
735 length := val.Type().Length()
736 return BoolVal(int(index) < length && index >= 0)
738 panic("not a list, map, or tuple type")
742 // HasElement returns True if the receiver (which must be of a set type)
743 // has the given value as an element, or False if it does not.
745 // The result will be UnknownVal(Bool) if either the set or the
746 // given value are unknown.
748 // This method will panic if the receiver is not a set, or if it is a null set.
749 func (val Value) HasElement(elem Value) Value {
753 panic("not a set type")
755 if !val.IsKnown() || !elem.IsKnown() {
756 return UnknownVal(Bool)
759 panic("can't call HasElement on a nil value")
761 if ty.ElementType() != elem.Type() {
766 return BoolVal(s.Has(elem.v))
769 // Length returns the length of the receiver, which must be a collection type
770 // or tuple type, as a number value. If the receiver is not a compatible type
771 // then this method will panic.
773 // If the receiver is unknown then the result is also unknown.
775 // If the receiver is null then this function will panic.
777 // Note that Length is not supported for strings. To determine the length
778 // of a string, call AsString and take the length of the native Go string
780 func (val Value) Length() Value {
781 if val.Type().IsTupleType() {
782 // For tuples, we can return the length even if the value is not known.
783 return NumberIntVal(int64(val.Type().Length()))
787 return UnknownVal(Number)
790 return NumberIntVal(int64(val.LengthInt()))
793 // LengthInt is like Length except it returns an int. It has the same behavior
794 // as Length except that it will panic if the receiver is unknown.
796 // This is an integration method provided for the convenience of code bridging
797 // into Go's type system.
798 func (val Value) LengthInt() int {
799 if val.Type().IsTupleType() {
800 // For tuples, we can return the length even if the value is not known.
801 return val.Type().Length()
804 panic("value is not known")
807 panic("value is null")
812 case val.ty.IsListType():
813 return len(val.v.([]interface{}))
815 case val.ty.IsSetType():
816 return val.v.(set.Set).Length()
818 case val.ty.IsMapType():
819 return len(val.v.(map[string]interface{}))
822 panic("value is not a collection")
826 // ElementIterator returns an ElementIterator for iterating the elements
827 // of the receiver, which must be a collection type, a tuple type, or an object
828 // type. If called on a method of any other type, this method will panic.
830 // The value must be Known and non-Null, or this method will panic.
832 // If the receiver is of a list type, the returned keys will be of type Number
833 // and the values will be of the list's element type.
835 // If the receiver is of a map type, the returned keys will be of type String
836 // and the value will be of the map's element type. Elements are passed in
837 // ascending lexicographical order by key.
839 // If the receiver is of a set type, each element is returned as both the
840 // key and the value, since set members are their own identity.
842 // If the receiver is of a tuple type, the returned keys will be of type Number
843 // and the value will be of the corresponding element's type.
845 // If the receiver is of an object type, the returned keys will be of type
846 // String and the value will be of the corresponding attributes's type.
848 // ElementIterator is an integration method, so it cannot handle Unknown
849 // values. This method will panic if the receiver is Unknown.
850 func (val Value) ElementIterator() ElementIterator {
852 panic("can't use ElementIterator on unknown value")
855 panic("can't use ElementIterator on null value")
857 return elementIterator(val)
860 // CanIterateElements returns true if the receiver can support the
861 // ElementIterator method (and by extension, ForEachElement) without panic.
862 func (val Value) CanIterateElements() bool {
863 return canElementIterator(val)
866 // ForEachElement executes a given callback function for each element of
867 // the receiver, which must be a collection type or tuple type, or this method
870 // ForEachElement uses ElementIterator internally, and so the values passed
871 // to the callback are as described for ElementIterator.
873 // Returns true if the iteration exited early due to the callback function
874 // returning true, or false if the loop ran to completion.
876 // ForEachElement is an integration method, so it cannot handle Unknown
877 // values. This method will panic if the receiver is Unknown.
878 func (val Value) ForEachElement(cb ElementCallback) bool {
879 it := val.ElementIterator()
881 key, val := it.Element()
890 // Not returns the logical inverse of the receiver, which must be of type
891 // Bool or this method will panic.
892 func (val Value) Not() Value {
893 if shortCircuit := mustTypeCheck(Bool, Bool, val); shortCircuit != nil {
894 shortCircuit = forceShortCircuitType(shortCircuit, Bool)
898 return BoolVal(!val.v.(bool))
901 // And returns the result of logical AND with the receiver and the other given
902 // value, which must both be of type Bool or this method will panic.
903 func (val Value) And(other Value) Value {
904 if shortCircuit := mustTypeCheck(Bool, Bool, val, other); shortCircuit != nil {
905 shortCircuit = forceShortCircuitType(shortCircuit, Bool)
909 return BoolVal(val.v.(bool) && other.v.(bool))
912 // Or returns the result of logical OR with the receiver and the other given
913 // value, which must both be of type Bool or this method will panic.
914 func (val Value) Or(other Value) Value {
915 if shortCircuit := mustTypeCheck(Bool, Bool, val, other); shortCircuit != nil {
916 shortCircuit = forceShortCircuitType(shortCircuit, Bool)
920 return BoolVal(val.v.(bool) || other.v.(bool))
923 // LessThan returns True if the receiver is less than the other given value,
924 // which must both be numbers or this method will panic.
925 func (val Value) LessThan(other Value) Value {
926 if shortCircuit := mustTypeCheck(Number, Bool, val, other); shortCircuit != nil {
927 shortCircuit = forceShortCircuitType(shortCircuit, Bool)
931 return BoolVal(val.v.(*big.Float).Cmp(other.v.(*big.Float)) < 0)
934 // GreaterThan returns True if the receiver is greater than the other given
935 // value, which must both be numbers or this method will panic.
936 func (val Value) GreaterThan(other Value) Value {
937 if shortCircuit := mustTypeCheck(Number, Bool, val, other); shortCircuit != nil {
938 shortCircuit = forceShortCircuitType(shortCircuit, Bool)
942 return BoolVal(val.v.(*big.Float).Cmp(other.v.(*big.Float)) > 0)
945 // LessThanOrEqualTo is equivalent to LessThan and Equal combined with Or.
946 func (val Value) LessThanOrEqualTo(other Value) Value {
947 return val.LessThan(other).Or(val.Equals(other))
950 // GreaterThanOrEqualTo is equivalent to GreaterThan and Equal combined with Or.
951 func (val Value) GreaterThanOrEqualTo(other Value) Value {
952 return val.GreaterThan(other).Or(val.Equals(other))
955 // AsString returns the native string from a non-null, non-unknown cty.String
956 // value, or panics if called on any other value.
957 func (val Value) AsString() string {
958 if val.ty != String {
959 panic("not a string")
962 panic("value is null")
965 panic("value is unknown")
968 return val.v.(string)
971 // AsBigFloat returns a big.Float representation of a non-null, non-unknown
972 // cty.Number value, or panics if called on any other value.
974 // For more convenient conversions to other native numeric types, use the
976 func (val Value) AsBigFloat() *big.Float {
977 if val.ty != Number {
978 panic("not a number")
981 panic("value is null")
984 panic("value is unknown")
987 // Copy the float so that callers can't mutate our internal state
988 ret := *(val.v.(*big.Float))
993 // AsValueSlice returns a []cty.Value representation of a non-null, non-unknown
994 // value of any type that CanIterateElements, or panics if called on
997 // For more convenient conversions to slices of more specific types, use
998 // the "gocty" package.
999 func (val Value) AsValueSlice() []Value {
1000 l := val.LengthInt()
1005 ret := make([]Value, 0, l)
1006 for it := val.ElementIterator(); it.Next(); {
1007 _, v := it.Element()
1008 ret = append(ret, v)
1013 // AsValueMap returns a map[string]cty.Value representation of a non-null,
1014 // non-unknown value of any type that CanIterateElements, or panics if called
1015 // on any other value.
1017 // For more convenient conversions to maps of more specific types, use
1018 // the "gocty" package.
1019 func (val Value) AsValueMap() map[string]Value {
1020 l := val.LengthInt()
1025 ret := make(map[string]Value, l)
1026 for it := val.ElementIterator(); it.Next(); {
1027 k, v := it.Element()
1028 ret[k.AsString()] = v
1033 // AsValueSet returns a ValueSet representation of a non-null,
1034 // non-unknown value of any collection type, or panics if called
1035 // on any other value.
1037 // Unlike AsValueSlice and AsValueMap, this method requires specifically a
1038 // collection type (list, set or map) and does not allow structural types
1039 // (tuple or object), because the ValueSet type requires homogenous
1042 // The returned ValueSet can store only values of the receiver's element type.
1043 func (val Value) AsValueSet() ValueSet {
1044 if !val.Type().IsCollectionType() {
1045 panic("not a collection type")
1048 // We don't give the caller our own set.Set (assuming we're a cty.Set value)
1049 // because then the caller could mutate our internals, which is forbidden.
1050 // Instead, we will construct a new set and append our elements into it.
1051 ret := NewValueSet(val.Type().ElementType())
1052 for it := val.ElementIterator(); it.Next(); {
1053 _, v := it.Element()
1059 // EncapsulatedValue returns the native value encapsulated in a non-null,
1060 // non-unknown capsule-typed value, or panics if called on any other value.
1062 // The result is the same pointer that was passed to CapsuleVal to create
1063 // the value. Since cty considers values to be immutable, it is strongly
1064 // recommended to treat the encapsulated value itself as immutable too.
1065 func (val Value) EncapsulatedValue() interface{} {
1066 if !val.Type().IsCapsuleType() {
1067 panic("not a capsule-typed value")