diff options
Diffstat (limited to 'vendor/github.com/hashicorp/terraform/lang/funcs/string.go')
-rw-r--r-- | vendor/github.com/hashicorp/terraform/lang/funcs/string.go | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/vendor/github.com/hashicorp/terraform/lang/funcs/string.go b/vendor/github.com/hashicorp/terraform/lang/funcs/string.go new file mode 100644 index 0000000..c9ddf19 --- /dev/null +++ b/vendor/github.com/hashicorp/terraform/lang/funcs/string.go | |||
@@ -0,0 +1,280 @@ | |||
1 | package funcs | ||
2 | |||
3 | import ( | ||
4 | "fmt" | ||
5 | "regexp" | ||
6 | "sort" | ||
7 | "strings" | ||
8 | |||
9 | "github.com/zclconf/go-cty/cty" | ||
10 | "github.com/zclconf/go-cty/cty/function" | ||
11 | "github.com/zclconf/go-cty/cty/gocty" | ||
12 | ) | ||
13 | |||
14 | var JoinFunc = function.New(&function.Spec{ | ||
15 | Params: []function.Parameter{ | ||
16 | { | ||
17 | Name: "separator", | ||
18 | Type: cty.String, | ||
19 | }, | ||
20 | }, | ||
21 | VarParam: &function.Parameter{ | ||
22 | Name: "lists", | ||
23 | Type: cty.List(cty.String), | ||
24 | }, | ||
25 | Type: function.StaticReturnType(cty.String), | ||
26 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
27 | sep := args[0].AsString() | ||
28 | listVals := args[1:] | ||
29 | if len(listVals) < 1 { | ||
30 | return cty.UnknownVal(cty.String), fmt.Errorf("at least one list is required") | ||
31 | } | ||
32 | |||
33 | l := 0 | ||
34 | for _, list := range listVals { | ||
35 | if !list.IsWhollyKnown() { | ||
36 | return cty.UnknownVal(cty.String), nil | ||
37 | } | ||
38 | l += list.LengthInt() | ||
39 | } | ||
40 | |||
41 | items := make([]string, 0, l) | ||
42 | for ai, list := range listVals { | ||
43 | ei := 0 | ||
44 | for it := list.ElementIterator(); it.Next(); { | ||
45 | _, val := it.Element() | ||
46 | if val.IsNull() { | ||
47 | if len(listVals) > 1 { | ||
48 | return cty.UnknownVal(cty.String), function.NewArgErrorf(ai+1, "element %d of list %d is null; cannot concatenate null values", ei, ai+1) | ||
49 | } | ||
50 | return cty.UnknownVal(cty.String), function.NewArgErrorf(ai+1, "element %d is null; cannot concatenate null values", ei) | ||
51 | } | ||
52 | items = append(items, val.AsString()) | ||
53 | ei++ | ||
54 | } | ||
55 | } | ||
56 | |||
57 | return cty.StringVal(strings.Join(items, sep)), nil | ||
58 | }, | ||
59 | }) | ||
60 | |||
61 | var SortFunc = function.New(&function.Spec{ | ||
62 | Params: []function.Parameter{ | ||
63 | { | ||
64 | Name: "list", | ||
65 | Type: cty.List(cty.String), | ||
66 | }, | ||
67 | }, | ||
68 | Type: function.StaticReturnType(cty.List(cty.String)), | ||
69 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
70 | listVal := args[0] | ||
71 | |||
72 | if !listVal.IsWhollyKnown() { | ||
73 | // If some of the element values aren't known yet then we | ||
74 | // can't yet preduct the order of the result. | ||
75 | return cty.UnknownVal(retType), nil | ||
76 | } | ||
77 | if listVal.LengthInt() == 0 { // Easy path | ||
78 | return listVal, nil | ||
79 | } | ||
80 | |||
81 | list := make([]string, 0, listVal.LengthInt()) | ||
82 | for it := listVal.ElementIterator(); it.Next(); { | ||
83 | iv, v := it.Element() | ||
84 | if v.IsNull() { | ||
85 | return cty.UnknownVal(retType), fmt.Errorf("given list element %s is null; a null string cannot be sorted", iv.AsBigFloat().String()) | ||
86 | } | ||
87 | list = append(list, v.AsString()) | ||
88 | } | ||
89 | |||
90 | sort.Strings(list) | ||
91 | retVals := make([]cty.Value, len(list)) | ||
92 | for i, s := range list { | ||
93 | retVals[i] = cty.StringVal(s) | ||
94 | } | ||
95 | return cty.ListVal(retVals), nil | ||
96 | }, | ||
97 | }) | ||
98 | |||
99 | var SplitFunc = function.New(&function.Spec{ | ||
100 | Params: []function.Parameter{ | ||
101 | { | ||
102 | Name: "separator", | ||
103 | Type: cty.String, | ||
104 | }, | ||
105 | { | ||
106 | Name: "str", | ||
107 | Type: cty.String, | ||
108 | }, | ||
109 | }, | ||
110 | Type: function.StaticReturnType(cty.List(cty.String)), | ||
111 | Impl: func(args []cty.Value, retType cty.Type) (cty.Value, error) { | ||
112 | sep := args[0].AsString() | ||
113 | str := args[1].AsString() | ||
114 | elems := strings.Split(str, sep) | ||
115 | elemVals := make([]cty.Value, len(elems)) | ||
116 | for i, s := range elems { | ||
117 | elemVals[i] = cty.StringVal(s) | ||
118 | } | ||
119 | if len(elemVals) == 0 { | ||
120 | return cty.ListValEmpty(cty.String), nil | ||
121 | } | ||
122 | return cty.ListVal(elemVals), nil | ||
123 | }, | ||
124 | }) | ||
125 | |||
126 | // ChompFunc constructions a function that removes newline characters at the end of a string. | ||
127 | var ChompFunc = function.New(&function.Spec{ | ||
128 | Params: []function.Parameter{ | ||
129 | { | ||
130 | Name: "str", | ||
131 | Type: cty.String, | ||
132 | }, | ||
133 | }, | ||
134 | Type: function.StaticReturnType(cty.String), | ||
135 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
136 | newlines := regexp.MustCompile(`(?:\r\n?|\n)*\z`) | ||
137 | return cty.StringVal(newlines.ReplaceAllString(args[0].AsString(), "")), nil | ||
138 | }, | ||
139 | }) | ||
140 | |||
141 | // IndentFunc constructions a function that adds a given number of spaces to the | ||
142 | // beginnings of all but the first line in a given multi-line string. | ||
143 | var IndentFunc = function.New(&function.Spec{ | ||
144 | Params: []function.Parameter{ | ||
145 | { | ||
146 | Name: "spaces", | ||
147 | Type: cty.Number, | ||
148 | }, | ||
149 | { | ||
150 | Name: "str", | ||
151 | Type: cty.String, | ||
152 | }, | ||
153 | }, | ||
154 | Type: function.StaticReturnType(cty.String), | ||
155 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
156 | var spaces int | ||
157 | if err := gocty.FromCtyValue(args[0], &spaces); err != nil { | ||
158 | return cty.UnknownVal(cty.String), err | ||
159 | } | ||
160 | data := args[1].AsString() | ||
161 | pad := strings.Repeat(" ", spaces) | ||
162 | return cty.StringVal(strings.Replace(data, "\n", "\n"+pad, -1)), nil | ||
163 | }, | ||
164 | }) | ||
165 | |||
166 | // ReplaceFunc constructions a function that searches a given string for another | ||
167 | // given substring, and replaces each occurence with a given replacement string. | ||
168 | var ReplaceFunc = function.New(&function.Spec{ | ||
169 | Params: []function.Parameter{ | ||
170 | { | ||
171 | Name: "str", | ||
172 | Type: cty.String, | ||
173 | }, | ||
174 | { | ||
175 | Name: "substr", | ||
176 | Type: cty.String, | ||
177 | }, | ||
178 | { | ||
179 | Name: "replace", | ||
180 | Type: cty.String, | ||
181 | }, | ||
182 | }, | ||
183 | Type: function.StaticReturnType(cty.String), | ||
184 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
185 | str := args[0].AsString() | ||
186 | substr := args[1].AsString() | ||
187 | replace := args[2].AsString() | ||
188 | |||
189 | // We search/replace using a regexp if the string is surrounded | ||
190 | // in forward slashes. | ||
191 | if len(substr) > 1 && substr[0] == '/' && substr[len(substr)-1] == '/' { | ||
192 | re, err := regexp.Compile(substr[1 : len(substr)-1]) | ||
193 | if err != nil { | ||
194 | return cty.UnknownVal(cty.String), err | ||
195 | } | ||
196 | |||
197 | return cty.StringVal(re.ReplaceAllString(str, replace)), nil | ||
198 | } | ||
199 | |||
200 | return cty.StringVal(strings.Replace(str, substr, replace, -1)), nil | ||
201 | }, | ||
202 | }) | ||
203 | |||
204 | // TitleFunc constructions a function that converts the first letter of each word | ||
205 | // in the given string to uppercase. | ||
206 | var TitleFunc = function.New(&function.Spec{ | ||
207 | Params: []function.Parameter{ | ||
208 | { | ||
209 | Name: "str", | ||
210 | Type: cty.String, | ||
211 | }, | ||
212 | }, | ||
213 | Type: function.StaticReturnType(cty.String), | ||
214 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
215 | return cty.StringVal(strings.Title(args[0].AsString())), nil | ||
216 | }, | ||
217 | }) | ||
218 | |||
219 | // TrimSpaceFunc constructions a function that removes any space characters from | ||
220 | // the start and end of the given string. | ||
221 | var TrimSpaceFunc = function.New(&function.Spec{ | ||
222 | Params: []function.Parameter{ | ||
223 | { | ||
224 | Name: "str", | ||
225 | Type: cty.String, | ||
226 | }, | ||
227 | }, | ||
228 | Type: function.StaticReturnType(cty.String), | ||
229 | Impl: func(args []cty.Value, retType cty.Type) (ret cty.Value, err error) { | ||
230 | return cty.StringVal(strings.TrimSpace(args[0].AsString())), nil | ||
231 | }, | ||
232 | }) | ||
233 | |||
234 | // Join concatenates together the string elements of one or more lists with a | ||
235 | // given separator. | ||
236 | func Join(sep cty.Value, lists ...cty.Value) (cty.Value, error) { | ||
237 | args := make([]cty.Value, len(lists)+1) | ||
238 | args[0] = sep | ||
239 | copy(args[1:], lists) | ||
240 | return JoinFunc.Call(args) | ||
241 | } | ||
242 | |||
243 | // Sort re-orders the elements of a given list of strings so that they are | ||
244 | // in ascending lexicographical order. | ||
245 | func Sort(list cty.Value) (cty.Value, error) { | ||
246 | return SortFunc.Call([]cty.Value{list}) | ||
247 | } | ||
248 | |||
249 | // Split divides a given string by a given separator, returning a list of | ||
250 | // strings containing the characters between the separator sequences. | ||
251 | func Split(sep, str cty.Value) (cty.Value, error) { | ||
252 | return SplitFunc.Call([]cty.Value{sep, str}) | ||
253 | } | ||
254 | |||
255 | // Chomp removes newline characters at the end of a string. | ||
256 | func Chomp(str cty.Value) (cty.Value, error) { | ||
257 | return ChompFunc.Call([]cty.Value{str}) | ||
258 | } | ||
259 | |||
260 | // Indent adds a given number of spaces to the beginnings of all but the first | ||
261 | // line in a given multi-line string. | ||
262 | func Indent(spaces, str cty.Value) (cty.Value, error) { | ||
263 | return IndentFunc.Call([]cty.Value{spaces, str}) | ||
264 | } | ||
265 | |||
266 | // Replace searches a given string for another given substring, | ||
267 | // and replaces all occurences with a given replacement string. | ||
268 | func Replace(str, substr, replace cty.Value) (cty.Value, error) { | ||
269 | return ReplaceFunc.Call([]cty.Value{str, substr, replace}) | ||
270 | } | ||
271 | |||
272 | // Title converts the first letter of each word in the given string to uppercase. | ||
273 | func Title(str cty.Value) (cty.Value, error) { | ||
274 | return TitleFunc.Call([]cty.Value{str}) | ||
275 | } | ||
276 | |||
277 | // TrimSpace removes any space characters from the start and end of the given string. | ||
278 | func TrimSpace(str cty.Value) (cty.Value, error) { | ||
279 | return TrimSpaceFunc.Call([]cty.Value{str}) | ||
280 | } | ||