How to convert the string representation of a Terraform set of strings to a slice of strings

Viewed 391

I've a terratest where I get an output from terraform like so s := "[a b]". The terraform output's value = toset([resource.name]), it's a set of strings.

Apparently fmt.Printf("%T", s) returns string. I need to iterate to perform further validation.

I tried the below approach but errors!

var v interface{}
if err := json.Unmarshal([]byte(s), &v); err != nil {
    fmt.Println(err)
}

My current implementation to convert to a slice is:

s := "[a b]"
s1 := strings.Fields(strings.Trim(s, "[]"))
for _, v:= range s1 {
    fmt.Println("v -> " + v)
}

Looking for suggestions to current approach or alternative ways to convert to arr/slice that I should be considering. Appreciate any inputs. Thanks.

2 Answers

Actually your current implementation seems just fine.

You can't use JSON unmarshaling because JSON strings must be enclosed in double quotes ".

Instead strings.Fields does just that, it splits a string on one or more characters that match unicode.IsSpace, which is \t, \n, \v. \f, \r and .

Moeover this works also if terraform sends an empty set as [], as stated in the documentation:

returning [...] an empty slice if s contains only white space.

...which includes the case of s being empty "" altogether.

In case you need additional control over this, you can use strings.FieldsFunc, which accepts a function of type func(rune) bool so you can determine yourself what constitutes a "space". But since your input string comes from terraform, I guess it's going to be well-behaved enough.

There may be third-party packages that already implement this functionality, but unless your program already imports them, I think the native solution based on the standard lib is always preferrable.


unicode.IsSpace actually includes also the higher runes 0x85 and 0xA0, in which case strings.Fields calls FieldsFunc(s, unicode.IsSpace)

Related