@@ -61,14 +61,25 @@ func (a *stringSliceArgs) Slice() []string {
6161 return ret
6262}
6363
64+ // Argument captures a positional argument that can
65+ // be parsed
6466type Argument interface {
67+ // which this argument can be accessed using the given name
68+ HasName (string ) bool
69+
70+ // Parse the given args and return unparsed args and/or error
6571 Parse ([]string ) ([]string , error )
72+
73+ // The usage template for this argument to use in help
6674 Usage () string
75+
76+ // The Value of this Arg
77+ Get () any
6778}
6879
6980// AnyArguments to differentiate between no arguments(nil) vs aleast one
7081var AnyArguments = []Argument {
71- & StringArg {
82+ & StringArgs {
7283 Max : - 1 ,
7384 },
7485}
@@ -77,14 +88,78 @@ type ArgumentBase[T any, C any, VC ValueCreator[T, C]] struct {
7788 Name string `json:"name"` // the name of this argument
7889 Value T `json:"value"` // the default value of this argument
7990 Destination * T `json:"-"` // the destination point for this argument
80- Values * []T `json:"-"` // all the values of this argument, only if multiple are supported
91+ UsageText string `json:"usageText"` // the usage text to show
92+ Config C `json:"config"` // config for this argument similar to Flag Config
93+
94+ value * T
95+ }
96+
97+ func (a * ArgumentBase [T , C , VC ]) HasName (s string ) bool {
98+ return s == a .Name
99+ }
100+
101+ func (a * ArgumentBase [T , C , VC ]) Usage () string {
102+ if a .UsageText != "" {
103+ return a .UsageText
104+ }
105+
106+ usageFormat := "%[1]s"
107+ return fmt .Sprintf (usageFormat , a .Name )
108+ }
109+
110+ func (a * ArgumentBase [T , C , VC ]) Parse (s []string ) ([]string , error ) {
111+ tracef ("calling arg%[1] parse with args %[2]" , a .Name , s )
112+
113+ var vc VC
114+ var t T
115+ value := vc .Create (a .Value , & t , a .Config )
116+ a .value = & t
117+
118+ tracef ("attempting arg%[1] parse" , & a .Name )
119+ if len (s ) > 0 {
120+ if err := value .Set (s [0 ]); err != nil {
121+ return s , err
122+ }
123+ * a .value = value .Get ().(T )
124+ tracef ("set arg%[1] one value" , a .Name , * a .value )
125+ }
126+
127+ if a .Destination != nil {
128+ tracef ("setting destination" )
129+ * a .Destination = * a .value
130+ }
131+
132+ if len (s ) > 0 {
133+ return s [1 :], nil
134+ }
135+ return s , nil
136+ }
137+
138+ func (a * ArgumentBase [T , C , VC ]) Get () any {
139+ if a .value != nil {
140+ return * a .value
141+ }
142+ return a .Value
143+ }
144+
145+ // ArgumentsBase is a base type for slice arguments
146+ type ArgumentsBase [T any , C any , VC ValueCreator [T , C ]] struct {
147+ Name string `json:"name"` // the name of this argument
148+ Value T `json:"value"` // the default value of this argument
149+ Destination * []T `json:"-"` // the destination point for this argument
81150 UsageText string `json:"usageText"` // the usage text to show
82151 Min int `json:"minTimes"` // the min num of occurrences of this argument
83152 Max int `json:"maxTimes"` // the max num of occurrences of this argument, set to -1 for unlimited
84153 Config C `json:"config"` // config for this argument similar to Flag Config
154+
155+ values []T
85156}
86157
87- func (a * ArgumentBase [T , C , VC ]) Usage () string {
158+ func (a * ArgumentsBase [T , C , VC ]) HasName (s string ) bool {
159+ return s == a .Name
160+ }
161+
162+ func (a * ArgumentsBase [T , C , VC ]) Usage () string {
88163 if a .UsageText != "" {
89164 return a .UsageText
90165 }
@@ -102,7 +177,7 @@ func (a *ArgumentBase[T, C, VC]) Usage() string {
102177 return fmt .Sprintf (usageFormat , a .Name )
103178}
104179
105- func (a * ArgumentBase [T , C , VC ]) Parse (s []string ) ([]string , error ) {
180+ func (a * ArgumentsBase [T , C , VC ]) Parse (s []string ) ([]string , error ) {
106181 tracef ("calling arg%[1] parse with args %[2]" , & a .Name , s )
107182 if a .Max == 0 {
108183 fmt .Printf ("WARNING args %s has max 0, not parsing argument\n " , a .Name )
@@ -117,13 +192,15 @@ func (a *ArgumentBase[T, C, VC]) Parse(s []string) ([]string, error) {
117192 var vc VC
118193 var t T
119194 value := vc .Create (a .Value , & t , a .Config )
120- values : = []T {}
195+ a . values = []T {}
121196
197+ tracef ("attempting arg%[1] parse" , & a .Name )
122198 for _ , arg := range s {
123199 if err := value .Set (arg ); err != nil {
124200 return s , err
125201 }
126- values = append (values , value .Get ().(T ))
202+ tracef ("set arg%[1] one value" , & a .Name , value .Get ().(T ))
203+ a .values = append (a .values , value .Get ().(T ))
127204 count ++
128205 if count >= a .Max && a .Max > - 1 {
129206 break
@@ -133,36 +210,173 @@ func (a *ArgumentBase[T, C, VC]) Parse(s []string) ([]string, error) {
133210 return s , fmt .Errorf ("sufficient count of arg %s not provided, given %d expected %d" , a .Name , count , a .Min )
134211 }
135212
136- if a .Values == nil {
137- a .Values = & values
138- } else if count > 0 {
139- * a .Values = values
140- }
141-
142- if a .Max == 1 && a .Destination != nil {
143- if len (values ) > 0 {
144- * a .Destination = values [0 ]
145- } else {
146- * a .Destination = t
147- }
213+ if a .Destination != nil {
214+ tracef ("appending destination" )
215+ * a .Destination = a .values // append(*a.Destination, a.values...)
148216 }
149217
150218 return s [count :], nil
151219}
152220
221+ func (a * ArgumentsBase [T , C , VC ]) Get () any {
222+ if a .values != nil {
223+ return a .values
224+ }
225+ return []T {}
226+ }
227+
153228type (
154- FloatArg = ArgumentBase [float64 , NoConfig , floatValue ]
155- IntArg = ArgumentBase [int , IntegerConfig , intValue [int ]]
156- Int8Arg = ArgumentBase [int8 , IntegerConfig , intValue [int8 ]]
157- Int16Arg = ArgumentBase [int16 , IntegerConfig , intValue [int16 ]]
158- Int32Arg = ArgumentBase [int32 , IntegerConfig , intValue [int32 ]]
159- Int64Arg = ArgumentBase [int64 , IntegerConfig , intValue [int64 ]]
160- StringArg = ArgumentBase [string , StringConfig , stringValue ]
161- StringMapArg = ArgumentBase [map [string ]string , StringConfig , StringMap ]
162- TimestampArg = ArgumentBase [time.Time , TimestampConfig , timestampValue ]
163- UintArg = ArgumentBase [uint , IntegerConfig , uintValue [uint ]]
164- Uint8Arg = ArgumentBase [uint8 , IntegerConfig , uintValue [uint8 ]]
165- Uint16Arg = ArgumentBase [uint16 , IntegerConfig , uintValue [uint16 ]]
166- Uint32Arg = ArgumentBase [uint32 , IntegerConfig , uintValue [uint32 ]]
167- Uint64Arg = ArgumentBase [uint64 , IntegerConfig , uintValue [uint64 ]]
229+ FloatArg = ArgumentBase [float64 , NoConfig , floatValue ]
230+ IntArg = ArgumentBase [int , IntegerConfig , intValue [int ]]
231+ Int8Arg = ArgumentBase [int8 , IntegerConfig , intValue [int8 ]]
232+ Int16Arg = ArgumentBase [int16 , IntegerConfig , intValue [int16 ]]
233+ Int32Arg = ArgumentBase [int32 , IntegerConfig , intValue [int32 ]]
234+ Int64Arg = ArgumentBase [int64 , IntegerConfig , intValue [int64 ]]
235+ StringArg = ArgumentBase [string , StringConfig , stringValue ]
236+ StringMapArgs = ArgumentBase [map [string ]string , StringConfig , StringMap ]
237+ TimestampArg = ArgumentBase [time.Time , TimestampConfig , timestampValue ]
238+ UintArg = ArgumentBase [uint , IntegerConfig , uintValue [uint ]]
239+ Uint8Arg = ArgumentBase [uint8 , IntegerConfig , uintValue [uint8 ]]
240+ Uint16Arg = ArgumentBase [uint16 , IntegerConfig , uintValue [uint16 ]]
241+ Uint32Arg = ArgumentBase [uint32 , IntegerConfig , uintValue [uint32 ]]
242+ Uint64Arg = ArgumentBase [uint64 , IntegerConfig , uintValue [uint64 ]]
243+
244+ FloatArgs = ArgumentsBase [float64 , NoConfig , floatValue ]
245+ IntArgs = ArgumentsBase [int , IntegerConfig , intValue [int ]]
246+ Int8Args = ArgumentsBase [int8 , IntegerConfig , intValue [int8 ]]
247+ Int16Args = ArgumentsBase [int16 , IntegerConfig , intValue [int16 ]]
248+ Int32Args = ArgumentsBase [int32 , IntegerConfig , intValue [int32 ]]
249+ Int64Args = ArgumentsBase [int64 , IntegerConfig , intValue [int64 ]]
250+ StringArgs = ArgumentsBase [string , StringConfig , stringValue ]
251+ TimestampArgs = ArgumentsBase [time.Time , TimestampConfig , timestampValue ]
252+ UintArgs = ArgumentsBase [uint , IntegerConfig , uintValue [uint ]]
253+ Uint8Args = ArgumentsBase [uint8 , IntegerConfig , uintValue [uint8 ]]
254+ Uint16Args = ArgumentsBase [uint16 , IntegerConfig , uintValue [uint16 ]]
255+ Uint32Args = ArgumentsBase [uint32 , IntegerConfig , uintValue [uint32 ]]
256+ Uint64Args = ArgumentsBase [uint64 , IntegerConfig , uintValue [uint64 ]]
168257)
258+
259+ func (c * Command ) getArgValue (name string ) any {
260+ tracef ("command %s looking for args %s" , c .Name , name )
261+ for _ , arg := range c .Arguments {
262+ if arg .HasName (name ) {
263+ tracef ("command %s found args %s" , c .Name , name )
264+ return arg .Get ()
265+ }
266+ }
267+ tracef ("command %s did not find args %s" , c .Name , name )
268+ return nil
269+ }
270+
271+ func arg [T any ](name string , c * Command ) T {
272+ val := c .getArgValue (name )
273+ if a , ok := val .(T ); ok {
274+ return a
275+ }
276+ var zero T
277+ return zero
278+ }
279+
280+ func (c * Command ) StringArg (name string ) string {
281+ return arg [string ](name , c )
282+ }
283+
284+ func (c * Command ) StringArgs (name string ) []string {
285+ return arg [[]string ](name , c )
286+ }
287+
288+ func (c * Command ) FloatArg (name string ) float64 {
289+ return arg [float64 ](name , c )
290+ }
291+
292+ func (c * Command ) FloatArgs (name string ) []float64 {
293+ return arg [[]float64 ](name , c )
294+ }
295+
296+ func (c * Command ) IntArg (name string ) int {
297+ return arg [int ](name , c )
298+ }
299+
300+ func (c * Command ) IntArgs (name string ) []int {
301+ return arg [[]int ](name , c )
302+ }
303+
304+ func (c * Command ) Int8Arg (name string ) int8 {
305+ return arg [int8 ](name , c )
306+ }
307+
308+ func (c * Command ) Int8Args (name string ) []int8 {
309+ return arg [[]int8 ](name , c )
310+ }
311+
312+ func (c * Command ) Int16Arg (name string ) int16 {
313+ return arg [int16 ](name , c )
314+ }
315+
316+ func (c * Command ) Int16Args (name string ) []int16 {
317+ return arg [[]int16 ](name , c )
318+ }
319+
320+ func (c * Command ) Int32Arg (name string ) int32 {
321+ return arg [int32 ](name , c )
322+ }
323+
324+ func (c * Command ) Int32Args (name string ) []int32 {
325+ return arg [[]int32 ](name , c )
326+ }
327+
328+ func (c * Command ) Int64Arg (name string ) int64 {
329+ return arg [int64 ](name , c )
330+ }
331+
332+ func (c * Command ) Int64Args (name string ) []int64 {
333+ return arg [[]int64 ](name , c )
334+ }
335+
336+ func (c * Command ) UintArg (name string ) uint {
337+ return arg [uint ](name , c )
338+ }
339+
340+ func (c * Command ) Uint8Arg (name string ) uint8 {
341+ return arg [uint8 ](name , c )
342+ }
343+
344+ func (c * Command ) Uint16Arg (name string ) uint16 {
345+ return arg [uint16 ](name , c )
346+ }
347+
348+ func (c * Command ) Uint32Arg (name string ) uint32 {
349+ return arg [uint32 ](name , c )
350+ }
351+
352+ func (c * Command ) Uint64Arg (name string ) uint64 {
353+ return arg [uint64 ](name , c )
354+ }
355+
356+ func (c * Command ) UintArgs (name string ) []uint {
357+ return arg [[]uint ](name , c )
358+ }
359+
360+ func (c * Command ) Uint8Args (name string ) []uint8 {
361+ return arg [[]uint8 ](name , c )
362+ }
363+
364+ func (c * Command ) Uint16Args (name string ) []uint16 {
365+ return arg [[]uint16 ](name , c )
366+ }
367+
368+ func (c * Command ) Uint32Args (name string ) []uint32 {
369+ return arg [[]uint32 ](name , c )
370+ }
371+
372+ func (c * Command ) Uint64Args (name string ) []uint64 {
373+ return arg [[]uint64 ](name , c )
374+ }
375+
376+ func (c * Command ) TimestampArg (name string ) time.Time {
377+ return arg [time.Time ](name , c )
378+ }
379+
380+ func (c * Command ) TimestampArgs (name string ) []time.Time {
381+ return arg [[]time.Time ](name , c )
382+ }
0 commit comments