@@ -16,7 +16,7 @@ package types
16
16
17
17
import (
18
18
"encoding/json"
19
- "errors "
19
+ "fmt "
20
20
"strings"
21
21
)
22
22
@@ -33,24 +33,21 @@ type DevcontainerConfig struct {
33
33
RemoteUser string `json:"remoteUser,omitempty"`
34
34
}
35
35
36
- //nolint:tagliatelle
37
- type LifecycleCommand struct {
38
- CommandString string `json:"commandString,omitempty"`
39
- CommandArray []string `json:"commandArray,omitempty"`
40
- // Map to store commands by tags
41
- CommandMap map [string ]string `json:"commandMap,omitempty"`
42
- CommandMapArray map [string ][]string `json:"commandMapArray,omitempty"`
43
- Discriminator string `json:"-"` // Tracks the original type for proper re-marshaling
44
- }
45
-
46
36
// Constants for discriminator values.
47
37
const (
48
- TypeString = "string"
49
- TypeArray = "array"
50
- TypeCommandMapString = "commandMap"
51
- TypeCommandMapArray = "commandMapArray"
38
+ TypeString = "string"
39
+ TypeArray = "array"
40
+ TypeCommandMap = "commandMap"
52
41
)
53
42
43
+ //nolint:tagliatelle
44
+ type LifecycleCommand struct {
45
+ CommandString string `json:"commandString,omitempty"`
46
+ CommandArray []string `json:"commandArray,omitempty"`
47
+ CommandMap map [string ]any `json:"commandMap,omitempty"`
48
+ Discriminator string `json:"-"` // Tracks the original type for proper re-marshaling
49
+ }
50
+
54
51
func (lc * LifecycleCommand ) UnmarshalJSON (data []byte ) error {
55
52
// Try to unmarshal as a single string
56
53
var commandStr string
@@ -59,28 +56,43 @@ func (lc *LifecycleCommand) UnmarshalJSON(data []byte) error {
59
56
lc .Discriminator = TypeString
60
57
return nil
61
58
}
59
+
62
60
// Try to unmarshal as an array of strings
63
61
var commandArr []string
64
62
if err := json .Unmarshal (data , & commandArr ); err == nil {
65
63
lc .CommandArray = commandArr
66
64
lc .Discriminator = TypeArray
67
65
return nil
68
66
}
69
- // Try to unmarshal as a map of commands (tags to commands)
70
- var commandMap map [string ]string
71
- if err := json .Unmarshal (data , & commandMap ); err == nil {
72
- lc .CommandMap = commandMap
73
- lc .Discriminator = TypeCommandMapString
74
- return nil
75
- }
76
- // Try to unmarshal as a CommandMapArray
77
- var commandMapArray map [string ][]string
78
- if err := json .Unmarshal (data , & commandMapArray ); err == nil {
79
- lc .CommandMapArray = commandMapArray
80
- lc .Discriminator = TypeCommandMapArray
67
+
68
+ // Try to unmarshal as a map with mixed types
69
+ var rawMap map [string ]any
70
+ if err := json .Unmarshal (data , & rawMap ); err == nil {
71
+ for key , value := range rawMap {
72
+ switch v := value .(type ) {
73
+ case string :
74
+ // Valid string value
75
+ case []interface {}:
76
+ // Convert []interface{} to []string
77
+ var strArray []string
78
+ for _ , item := range v {
79
+ if str , ok := item .(string ); ok {
80
+ strArray = append (strArray , str )
81
+ } else {
82
+ return fmt .Errorf ("invalid format: array contains non-string value" )
83
+ }
84
+ }
85
+ rawMap [key ] = strArray
86
+ default :
87
+ return fmt .Errorf ("invalid format: map contains unsupported type" )
88
+ }
89
+ }
90
+ lc .CommandMap = rawMap
91
+ lc .Discriminator = TypeCommandMap
81
92
return nil
82
93
}
83
- return errors .New ("invalid format: must be string, []string, map[string]string, or map[string][]string" )
94
+
95
+ return fmt .Errorf ("invalid format: must be string, []string, or map[string]any" )
84
96
}
85
97
86
98
func (lc * LifecycleCommand ) MarshalJSON () ([]byte , error ) {
@@ -89,32 +101,29 @@ func (lc *LifecycleCommand) MarshalJSON() ([]byte, error) {
89
101
return json .Marshal (lc .CommandString )
90
102
case TypeArray :
91
103
return json .Marshal (lc .CommandArray )
92
- case TypeCommandMapString :
104
+ case TypeCommandMap :
93
105
return json .Marshal (lc .CommandMap )
94
- case TypeCommandMapArray :
95
- return json .Marshal (lc .CommandMapArray )
96
106
default :
97
- return nil , errors . New ("unknown type for LifecycleCommand" )
107
+ return nil , fmt . Errorf ("unknown type for LifecycleCommand" )
98
108
}
99
109
}
100
110
101
111
// ToCommandArray converts the LifecycleCommand into a slice of full commands.
102
112
func (lc * LifecycleCommand ) ToCommandArray () []string {
103
- switch {
104
- case lc . CommandString != "" :
113
+ switch lc . Discriminator {
114
+ case TypeString :
105
115
return []string {lc .CommandString }
106
- case lc . CommandArray != nil :
116
+ case TypeArray :
107
117
return []string {strings .Join (lc .CommandArray , " " )}
108
- case lc .CommandMap != nil :
109
- var commands []string
110
- for _ , command := range lc .CommandMap {
111
- commands = append (commands , command )
112
- }
113
- return commands
114
- case lc .CommandMapArray != nil :
118
+ case TypeCommandMap :
115
119
var commands []string
116
- for _ , commandArray := range lc .CommandMapArray {
117
- commands = append (commands , strings .Join (commandArray , " " ))
120
+ for _ , value := range lc .CommandMap {
121
+ switch v := value .(type ) {
122
+ case string :
123
+ commands = append (commands , v )
124
+ case []string :
125
+ commands = append (commands , strings .Join (v , " " ))
126
+ }
118
127
}
119
128
return commands
120
129
default :
0 commit comments