What I want to achieve
I'm parsing IAM Policies in Go. In IAM Policies, most of the fields can be either a string or an array of strings. It's hard to think these decision trees in my head what I want is kind of exhaustive pattern matching.
What I did
I loeded a policy with json.Unmarshal
type Policy struct {
Version string `json:"Version"`
Id string `json:"ID,omitempty"`
Statements []Statement `json:"Statement"`
}
type Statement struct {
// ...
Action interface{} `json:"Action"` // string or array
// ...
}
And iterating over statements.
switch ele := st.Action.(type) {
case string:
action, _ := expandAction(ele, data)
actions = append(actions, action...)
setter(i, actions)
case []string:
for _, a := range ele {
if strings.Contains(a, "*") {
exps, _ := expandAction(a, data)
actions = append(actions, exps...)
} else {
actions = append(actions, a)
}
setter(i, actions)
fmt.Println(actions)
}
default:
// interface{}
}
The Problem
It always goes to the default
case.
Can use reflection, but don't think I really should, since runtime could know types when json.Unnarshal
is called.
CodePudding user response:
As you can see from the official document the type for JSON array is []interface. If you update []string to []interface then you can run the related case block. However, if you have to sure that is array of string, reflection can provide it.