mccl/internal/manifest/argument.go

61 lines
1.6 KiB
Go
Executable File

package manifest
import (
"bytes"
"encoding/json"
)
// Argument is a special struct that was made to handle a mixed-typed array
// of arguments in a manifest.
//
// An argument in a manifest could be:
// - a single string
// - an object consists of rules array field and a value field that could be
// a single string or an array of strings.
type Argument struct {
Rules []Rule `json:"rules"`
Value []string `json:"value"`
}
// CheckRules returns true if all rules passed and a feature set in a rule if
// applicable, a FeatureUnknown otherwise.
func (a Argument) CheckRules() (ok bool, feature Feature) {
feature = FeatureUnknown
for _, r := range a.Rules {
ok, feature = r.Check()
if !ok {
return false, feature
}
}
return true, feature
}
// UnmarshalJSON had to be implemented because of mixed-typed nature of an
// arguments array in a manifest.
func (a *Argument) UnmarshalJSON(data []byte) error {
if data[0] == '"' {
a.Value = append(a.Value, string(data[1:len(data)-1]))
} else if data[0] == '{' && bytes.Contains(data, []byte("value\": \"")) {
singleValArg := struct {
Rules []Rule `json:"rules"`
Value string `json:"value"`
}{}
if err := json.Unmarshal(data, &singleValArg); err != nil {
return err
}
a.Rules = singleValArg.Rules
a.Value = append(a.Value, singleValArg.Value)
} else if data[0] == '{' {
multiValArg := struct {
Rules []Rule `json:"rules"`
Value []string `json:"value"`
}{}
if err := json.Unmarshal(data, &multiValArg); err != nil {
return err
}
a.Rules = multiValArg.Rules
a.Value = multiValArg.Value
}
return nil
}