1package cty
2
3import (
4	"fmt"
5)
6
7// TypeList instances represent specific list types. Each distinct ElementType
8// creates a distinct, non-equal list type.
9type typeMap struct {
10	typeImplSigil
11	ElementTypeT Type
12}
13
14// Map creates a map type with the given element Type.
15//
16// Map types are CollectionType implementations.
17func Map(elem Type) Type {
18	return Type{
19		typeMap{
20			ElementTypeT: elem,
21		},
22	}
23}
24
25// Equals returns true if the other Type is a map whose element type is
26// equal to that of the receiver.
27func (t typeMap) Equals(other Type) bool {
28	ot, isMap := other.typeImpl.(typeMap)
29	if !isMap {
30		return false
31	}
32
33	return t.ElementTypeT.Equals(ot.ElementTypeT)
34}
35
36func (t typeMap) FriendlyName(mode friendlyTypeNameMode) string {
37	elemName := t.ElementTypeT.friendlyNameMode(mode)
38	if mode == friendlyTypeConstraintName {
39		if t.ElementTypeT == DynamicPseudoType {
40			elemName = "any single type"
41		}
42	}
43	return "map of " + elemName
44}
45
46func (t typeMap) ElementType() Type {
47	return t.ElementTypeT
48}
49
50func (t typeMap) GoString() string {
51	return fmt.Sprintf("cty.Map(%#v)", t.ElementTypeT)
52}
53
54// IsMapType returns true if the given type is a list type, regardless of its
55// element type.
56func (t Type) IsMapType() bool {
57	_, ok := t.typeImpl.(typeMap)
58	return ok
59}
60
61// MapElementType is a convenience method that checks if the given type is
62// a map type, returning a pointer to its element type if so and nil
63// otherwise. This is intended to allow convenient conditional branches,
64// like so:
65//
66//     if et := t.MapElementType(); et != nil {
67//         // Do something with *et
68//     }
69func (t Type) MapElementType() *Type {
70	if lt, ok := t.typeImpl.(typeMap); ok {
71		return &lt.ElementTypeT
72	}
73	return nil
74}
75