Merge "services/device/device: refactor {instance|installation}StateFlag with 'generic'"
diff --git a/services/device/device/glob.go b/services/device/device/glob.go
index f442072..711e76d 100644
--- a/services/device/device/glob.go
+++ b/services/device/device/glob.go
@@ -316,16 +316,24 @@
return results
}
-type instanceStateFlag map[device.InstanceState]bool
+type genericStateFlag map[genericState]bool
-func (f *instanceStateFlag) apply(state device.InstanceState) bool {
+// genericState interface is meant to abstract device.InstanceState and
+// device.InstallationState. We only make use of the String method, but we
+// could also add Set and __VDLReflect to the method set to constrain the types
+// that can be used. Ultimately, however, the state constructor passed into
+// genericStateFlag.fromString is the gatekeeper as to what can be allowed in
+// the genericStateFlag set.
+type genericState fmt.Stringer
+
+func (f *genericStateFlag) apply(state genericState) bool {
if len(*f) == 0 {
return true
}
return (*f)[state]
}
-func (f *instanceStateFlag) String() string {
+func (f *genericStateFlag) String() string {
states := make([]string, 0, len(*f))
for s := range *f {
states = append(states, s.String())
@@ -334,52 +342,57 @@
return strings.Join(states, ",")
}
+func (f *genericStateFlag) fromString(s string, stateConstructor func(string) (genericState, error)) error {
+ states := strings.Split(s, ",")
+ for _, s := range states {
+ state, err := stateConstructor(s)
+ if err != nil {
+ return err
+ }
+ f.add(state)
+ }
+ return nil
+}
+
+func (f *genericStateFlag) add(s genericState) {
+ if *f == nil {
+ *f = make(genericStateFlag)
+ }
+ (*f)[s] = true
+}
+
+type instanceStateFlag struct {
+ genericStateFlag
+}
+
func (f *instanceStateFlag) Set(s string) error {
- if *f == nil {
- *f = make(instanceStateFlag)
- }
- states := strings.Split(s, ",")
+ return f.fromString(s, func(s string) (genericState, error) {
+ return device.InstanceStateFromString(s)
+ })
+}
+
+func InstanceStates(states ...device.InstanceState) (f instanceStateFlag) {
for _, s := range states {
- state, err := device.InstanceStateFromString(s)
- if err != nil {
- return err
- }
- (*f)[state] = true
+ f.add(s)
}
- return nil
+ return
}
-type installationStateFlag map[device.InstallationState]bool
-
-func (f *installationStateFlag) apply(state device.InstallationState) bool {
- if len(*f) == 0 {
- return true
- }
- return (*f)[state]
-}
-
-func (f *installationStateFlag) String() string {
- states := make([]string, 0, len(*f))
- for s := range *f {
- states = append(states, s.String())
- }
- sort.Strings(states)
- return strings.Join(states, ",")
+type installationStateFlag struct {
+ genericStateFlag
}
func (f *installationStateFlag) Set(s string) error {
- if *f == nil {
- *f = make(installationStateFlag)
- }
- states := strings.Split(s, ",")
+ return f.fromString(s, func(s string) (genericState, error) {
+ return device.InstallationStateFromString(s)
+ })
+}
+
+func InstallationStates(states ...device.InstallationState) (f installationStateFlag) {
for _, s := range states {
- state, err := device.InstallationStateFromString(s)
- if err != nil {
- return err
- }
- (*f)[state] = true
+ f.add(s)
}
- return nil
+ return
}
type parallelismFlag int
diff --git a/services/device/device/glob_test.go b/services/device/device/glob_test.go
index 1569872..084bd77 100644
--- a/services/device/device/glob_test.go
+++ b/services/device/device/glob_test.go
@@ -281,7 +281,7 @@
simplePrintHandler,
allGlobResponses,
allStatusResponses,
- cmd_device.GlobSettings{InstanceStateFilter: map[device.InstanceState]bool{device.InstanceStateUpdating: true}},
+ cmd_device.GlobSettings{InstanceStateFilter: cmd_device.InstanceStates(device.InstanceStateUpdating)},
allGlobArgs,
joinLines(app2Out, app4Out, app7Out, app3Out, app9Out, app6Out, app8Out),
"",
@@ -292,7 +292,7 @@
simplePrintHandler,
allGlobResponses,
allStatusResponses,
- cmd_device.GlobSettings{InstallationStateFilter: map[device.InstallationState]bool{device.InstallationStateActive: true}},
+ cmd_device.GlobSettings{InstallationStateFilter: cmd_device.InstallationStates(device.InstallationStateActive)},
allGlobArgs,
joinLines(app4Out, app7Out, app1Out, app3Out, app5Out, app9Out, app6Out, app8Out),
"",
@@ -304,7 +304,7 @@
allGlobResponses,
allStatusResponses,
cmd_device.GlobSettings{
- InstallationStateFilter: map[device.InstallationState]bool{device.InstallationStateActive: true},
+ InstallationStateFilter: cmd_device.InstallationStates(device.InstallationStateActive),
OnlyInstallations: true,
},
allGlobArgs,
@@ -318,7 +318,7 @@
allGlobResponses,
allStatusResponses,
cmd_device.GlobSettings{
- InstallationStateFilter: map[device.InstallationState]bool{device.InstallationStateActive: true},
+ InstallationStateFilter: cmd_device.InstallationStates(device.InstallationStateActive),
OnlyInstances: true,
},
allGlobArgs,
@@ -332,8 +332,8 @@
allGlobResponses,
allStatusResponses,
cmd_device.GlobSettings{
- InstanceStateFilter: map[device.InstanceState]bool{device.InstanceStateRunning: true},
- InstallationStateFilter: map[device.InstallationState]bool{device.InstallationStateUninstalled: true},
+ InstanceStateFilter: cmd_device.InstanceStates(device.InstanceStateRunning),
+ InstallationStateFilter: cmd_device.InstallationStates(device.InstallationStateUninstalled),
},
allGlobArgs,
joinLines(app2Out, app1Out, app6Out, app8Out),