1package toml
2
3// tomlType represents any Go type that corresponds to a TOML type.
4// While the first draft of the TOML spec has a simplistic type system that
5// probably doesn't need this level of sophistication, we seem to be militating
6// toward adding real composite types.
7type tomlType interface {
8	typeString() string
9}
10
11// typeEqual accepts any two types and returns true if they are equal.
12func typeEqual(t1, t2 tomlType) bool {
13	if t1 == nil || t2 == nil {
14		return false
15	}
16	return t1.typeString() == t2.typeString()
17}
18
19func typeIsHash(t tomlType) bool {
20	return typeEqual(t, tomlHash) || typeEqual(t, tomlArrayHash)
21}
22
23type tomlBaseType string
24
25func (btype tomlBaseType) typeString() string {
26	return string(btype)
27}
28
29func (btype tomlBaseType) String() string {
30	return btype.typeString()
31}
32
33var (
34	tomlInteger   tomlBaseType = "Integer"
35	tomlFloat     tomlBaseType = "Float"
36	tomlDatetime  tomlBaseType = "Datetime"
37	tomlString    tomlBaseType = "String"
38	tomlBool      tomlBaseType = "Bool"
39	tomlArray     tomlBaseType = "Array"
40	tomlHash      tomlBaseType = "Hash"
41	tomlArrayHash tomlBaseType = "ArrayHash"
42)
43
44// typeOfPrimitive returns a tomlType of any primitive value in TOML.
45// Primitive values are: Integer, Float, Datetime, String and Bool.
46//
47// Passing a lexer item other than the following will cause a BUG message
48// to occur: itemString, itemBool, itemInteger, itemFloat, itemDatetime.
49func (p *parser) typeOfPrimitive(lexItem item) tomlType {
50	switch lexItem.typ {
51	case itemInteger:
52		return tomlInteger
53	case itemFloat:
54		return tomlFloat
55	case itemDatetime:
56		return tomlDatetime
57	case itemString:
58		return tomlString
59	case itemMultilineString:
60		return tomlString
61	case itemRawString:
62		return tomlString
63	case itemRawMultilineString:
64		return tomlString
65	case itemBool:
66		return tomlBool
67	}
68	p.bug("Cannot infer primitive type of lex item '%s'.", lexItem)
69	panic("unreachable")
70}
71
72// typeOfArray returns a tomlType for an array given a list of types of its
73// values.
74//
75// In the current spec, if an array is homogeneous, then its type is always
76// "Array". If the array is not homogeneous, an error is generated.
77func (p *parser) typeOfArray(types []tomlType) tomlType {
78	// Empty arrays are cool.
79	if len(types) == 0 {
80		return tomlArray
81	}
82
83	theType := types[0]
84	for _, t := range types[1:] {
85		if !typeEqual(theType, t) {
86			p.panicf("Array contains values of type '%s' and '%s', but "+
87				"arrays must be homogeneous.", theType, t)
88		}
89	}
90	return tomlArray
91}
92