blob: 798cacd63a104d73d0a7d87a8cc498a26dd18196 [file] [log] [blame]
package cty
import (
"fmt"
)
type typeTuple struct {
typeImplSigil
ElemTypes []Type
}
// Tuple creates a tuple type with the given element types.
//
// After a slice is passed to this function the caller must no longer access
// the underlying array, since ownership is transferred to this library.
func Tuple(elemTypes []Type) Type {
return Type{
typeTuple{
ElemTypes: elemTypes,
},
}
}
func (t typeTuple) Equals(other Type) bool {
if ot, ok := other.typeImpl.(typeTuple); ok {
if len(t.ElemTypes) != len(ot.ElemTypes) {
// Fast path: if we don't have the same number of elements
// then we can't possibly be equal.
return false
}
for i, ty := range t.ElemTypes {
oty := ot.ElemTypes[i]
if !ok {
return false
}
if !oty.Equals(ty) {
return false
}
}
return true
}
return false
}
func (t typeTuple) FriendlyName(mode friendlyTypeNameMode) string {
// There isn't really a friendly way to write a tuple type due to its
// complexity, so we'll just do something English-ish. Callers will
// probably want to make some extra effort to avoid ever printing out
// a tuple type FriendlyName in its entirety. For example, could
// produce an error message by diffing two object types and saying
// something like "Expected attribute foo to be string, but got number".
// TODO: Finish this
return "tuple"
}
func (t typeTuple) GoString() string {
if len(t.ElemTypes) == 0 {
return "cty.EmptyTuple"
}
return fmt.Sprintf("cty.Tuple(%#v)", t.ElemTypes)
}
// EmptyTuple is a shorthand for Tuple([]Type{}), to more easily talk about
// the empty tuple type.
var EmptyTuple Type
// EmptyTupleVal is the only possible non-null, non-unknown value of type
// EmptyTuple.
var EmptyTupleVal Value
func init() {
EmptyTuple = Tuple([]Type{})
EmptyTupleVal = Value{
ty: EmptyTuple,
v: []interface{}{},
}
}
// IsTupleType returns true if the given type is an object type, regardless
// of its element type.
func (t Type) IsTupleType() bool {
_, ok := t.typeImpl.(typeTuple)
return ok
}
// Length returns the number of elements of the receiving tuple type.
// Will panic if the reciever isn't a tuple type; use IsTupleType to determine
// whether this operation will succeed.
func (t Type) Length() int {
if ot, ok := t.typeImpl.(typeTuple); ok {
return len(ot.ElemTypes)
}
panic("Length on non-tuple Type")
}
// TupleElementType returns the type of the element with the given index. Will
// panic if the receiver is not a tuple type (use IsTupleType to confirm)
// or if the index is out of range (use Length to confirm).
func (t Type) TupleElementType(idx int) Type {
if ot, ok := t.typeImpl.(typeTuple); ok {
return ot.ElemTypes[idx]
}
panic("TupleElementType on non-tuple Type")
}
// TupleElementTypes returns a slice of the recieving tuple type's element
// types. Will panic if the receiver is not a tuple type (use IsTupleType
// to confirm).
//
// The returned slice is part of the internal state of the type, and is provided
// for read access only. It is forbidden for any caller to modify the
// underlying array. For many purposes the element-related methods of Value
// are more appropriate and more convenient to use.
func (t Type) TupleElementTypes() []Type {
if ot, ok := t.typeImpl.(typeTuple); ok {
return ot.ElemTypes
}
panic("TupleElementTypes on non-tuple Type")
}