]>
Commit | Line | Data |
---|---|---|
15c0b25d AP |
1 | package cty |
2 | ||
3 | import ( | |
4 | "fmt" | |
5 | ) | |
6 | ||
7 | type typeTuple struct { | |
8 | typeImplSigil | |
9 | ElemTypes []Type | |
10 | } | |
11 | ||
12 | // Tuple creates a tuple type with the given element types. | |
13 | // | |
14 | // After a slice is passed to this function the caller must no longer access | |
15 | // the underlying array, since ownership is transferred to this library. | |
16 | func Tuple(elemTypes []Type) Type { | |
17 | return Type{ | |
18 | typeTuple{ | |
19 | ElemTypes: elemTypes, | |
20 | }, | |
21 | } | |
22 | } | |
23 | ||
24 | func (t typeTuple) Equals(other Type) bool { | |
25 | if ot, ok := other.typeImpl.(typeTuple); ok { | |
26 | if len(t.ElemTypes) != len(ot.ElemTypes) { | |
27 | // Fast path: if we don't have the same number of elements | |
28 | // then we can't possibly be equal. | |
29 | return false | |
30 | } | |
31 | ||
32 | for i, ty := range t.ElemTypes { | |
33 | oty := ot.ElemTypes[i] | |
34 | if !ok { | |
35 | return false | |
36 | } | |
37 | if !oty.Equals(ty) { | |
38 | return false | |
39 | } | |
40 | } | |
41 | ||
42 | return true | |
43 | } | |
44 | return false | |
45 | } | |
46 | ||
107c1cdb | 47 | func (t typeTuple) FriendlyName(mode friendlyTypeNameMode) string { |
15c0b25d AP |
48 | // There isn't really a friendly way to write a tuple type due to its |
49 | // complexity, so we'll just do something English-ish. Callers will | |
50 | // probably want to make some extra effort to avoid ever printing out | |
51 | // a tuple type FriendlyName in its entirety. For example, could | |
52 | // produce an error message by diffing two object types and saying | |
53 | // something like "Expected attribute foo to be string, but got number". | |
54 | // TODO: Finish this | |
55 | return "tuple" | |
56 | } | |
57 | ||
58 | func (t typeTuple) GoString() string { | |
59 | if len(t.ElemTypes) == 0 { | |
60 | return "cty.EmptyTuple" | |
61 | } | |
62 | return fmt.Sprintf("cty.Tuple(%#v)", t.ElemTypes) | |
63 | } | |
64 | ||
65 | // EmptyTuple is a shorthand for Tuple([]Type{}), to more easily talk about | |
66 | // the empty tuple type. | |
67 | var EmptyTuple Type | |
68 | ||
69 | // EmptyTupleVal is the only possible non-null, non-unknown value of type | |
70 | // EmptyTuple. | |
71 | var EmptyTupleVal Value | |
72 | ||
73 | func init() { | |
74 | EmptyTuple = Tuple([]Type{}) | |
75 | EmptyTupleVal = Value{ | |
76 | ty: EmptyTuple, | |
77 | v: []interface{}{}, | |
78 | } | |
79 | } | |
80 | ||
81 | // IsTupleType returns true if the given type is an object type, regardless | |
82 | // of its element type. | |
83 | func (t Type) IsTupleType() bool { | |
84 | _, ok := t.typeImpl.(typeTuple) | |
85 | return ok | |
86 | } | |
87 | ||
88 | // Length returns the number of elements of the receiving tuple type. | |
89 | // Will panic if the reciever isn't a tuple type; use IsTupleType to determine | |
90 | // whether this operation will succeed. | |
91 | func (t Type) Length() int { | |
92 | if ot, ok := t.typeImpl.(typeTuple); ok { | |
93 | return len(ot.ElemTypes) | |
94 | } | |
95 | panic("Length on non-tuple Type") | |
96 | } | |
97 | ||
98 | // TupleElementType returns the type of the element with the given index. Will | |
99 | // panic if the receiver is not a tuple type (use IsTupleType to confirm) | |
100 | // or if the index is out of range (use Length to confirm). | |
101 | func (t Type) TupleElementType(idx int) Type { | |
102 | if ot, ok := t.typeImpl.(typeTuple); ok { | |
103 | return ot.ElemTypes[idx] | |
104 | } | |
105 | panic("TupleElementType on non-tuple Type") | |
106 | } | |
107 | ||
108 | // TupleElementTypes returns a slice of the recieving tuple type's element | |
109 | // types. Will panic if the receiver is not a tuple type (use IsTupleType | |
110 | // to confirm). | |
111 | // | |
112 | // The returned slice is part of the internal state of the type, and is provided | |
113 | // for read access only. It is forbidden for any caller to modify the | |
114 | // underlying array. For many purposes the element-related methods of Value | |
115 | // are more appropriate and more convenient to use. | |
116 | func (t Type) TupleElementTypes() []Type { | |
117 | if ot, ok := t.typeImpl.(typeTuple); ok { | |
118 | return ot.ElemTypes | |
119 | } | |
120 | panic("TupleElementTypes on non-tuple Type") | |
121 | } |