-
Notifications
You must be signed in to change notification settings - Fork 0
/
constant.go
144 lines (120 loc) · 3.53 KB
/
constant.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
package constant
import (
"bytes"
"os"
"strconv"
"text/template"
)
// Returns the value of the node as defined by path.
// If the node's default value is nil an empty string is returned.
// If the envionment variable associated with the node is not equal to an empty string that value is used instead of the node's default value.
// Templates in the node's value are parsed (see sections Template, Template Context and Example for details).
func (n *Node) Str(path ...string) string {
node := n.Node(path...)
if node == nil {
return ""
}
node_fullname := node.FullName()
tmpl := node.Default()
node.mutex.RLock()
defer node.mutex.RUnlock()
parent := node.parent
if env := os.Getenv(node_fullname); env != "" {
tmpl = env
}
t, err := template.New("constant").Funcs(template.FuncMap{
"const": func(path ...string) string {
if len(path) == 1 && path[0] == node.name {
return ""
}
return parent.Str(path...)
},
"list": func() []string {
consts := parent.List()
for i, cnst := range consts {
if cnst == node.name {
consts = append(consts[:i], consts[i+1:]...)
}
}
return consts
},
"isset": func(path ...string) bool {
return parent.IsSet(path...)
},
}).Parse(tmpl)
if err != nil {
return ""
}
var byte_string bytes.Buffer
if err = t.Execute(&byte_string, nil); err != nil {
return ""
}
return byte_string.String()
}
// Alias of n.Str()
func (n *Node) String() string {
return n.Str()
}
// Returns the value of n.Str(path...) as an integer.
//
// Follows convention of strconv.Atoi (https://golang.org/pkg/strconv/#Atoi).
func (n *Node) Int(path ...string) (val int, err error) {
val, err = strconv.Atoi(n.Str(path...))
return
}
// Run n.Int(path...) but ignore errors
func (n *Node) IntI(path ...string) (val int) {
val, _ = n.Int(path...)
return
}
// Returns the value of n.Str(path...) as a float64.
//
// Follows convention of strconv.ParseFloat (https://golang.org/pkg/strconv/#ParseFloat).
func (n *Node) Float(bitSize int, path ...string) (val float64, err error) {
val, err = strconv.ParseFloat(n.Str(path...), bitSize)
return
}
// Run n.Float(bitSize, path...) but ignore errors
func (n *Node) FloatI(bitSize int, path ...string) (val float64) {
val, _ = n.Float(bitSize, path...)
return
}
// Returns the value of n.Str(path...) as a boolean.
//
// Follows convention of strconv.ParseBool (https://golang.org/pkg/strconv/#ParseBool).
func (n *Node) Bool(path ...string) (val bool, err error) {
val, err = strconv.ParseBool(n.Str(path...))
return
}
// Run n.Bool(path...) but ignore errors
func (n *Node) BoolI(path ...string) (val bool) {
val, _ = n.Bool(path...)
return
}
// Returns false if: the node as defined by path doesn't exist; the node's default value is nil; the node's default value it an empty string.
// Otherwise returns true.
func (n *Node) IsSet(path ...string) bool {
node := n.Node(path...)
if node == nil {
return false
}
node.mutex.RLock()
defer node.mutex.RUnlock()
return node.def_val != nil && *node.def_val != ""
}
// Returns the default value of node as defined by path.
// If the default value contains templates the templates will not be parsed.
// If the default value is not a string it will be converted to a string as per the strconv package (https://golang.org/pkg/strconv/).
// If the default value is nil an empty string is returned.
func (n *Node) Default(path ...string) string {
node := n.Node(path...)
if node == nil {
return ""
}
if !node.IsSet() {
return ""
}
node.mutex.RLock()
defer node.mutex.RUnlock()
return *node.def_val
}