@@ -28,9 +28,9 @@ import (
2828)
2929
3030const (
31- tagNameDc = `dc`
32- tagNameAd = `ad`
33- tagNameEg = `eg`
31+ tagNameDc = `dc` // description.
32+ tagNameAd = `ad` // additional
33+ tagNameEg = `eg` // examples.
3434 tagNameArg = `arg`
3535 tagNameRoot = `root`
3636)
@@ -61,7 +61,7 @@ func NewFromObject(object interface{}) (rootCmd *Command, err error) {
6161 }
6262
6363 // Root command creating.
64- rootCmd , err = newCommandFromObjectMeta (object )
64+ rootCmd , err = newCommandFromObjectMeta (object , "" )
6565 if err != nil {
6666 return
6767 }
@@ -76,17 +76,19 @@ func NewFromObject(object interface{}) (rootCmd *Command, err error) {
7676 }
7777 for i := 0 ; i < reflectValue .NumMethod (); i ++ {
7878 var (
79- method = reflectValue .Method (i )
80- methodCmd * Command
79+ method = reflectValue .Type ().Method (i )
80+ methodValue = reflectValue .Method (i )
81+ methodType = methodValue .Type ()
82+ methodCmd * Command
8183 )
82- methodCmd , err = newCommandFromMethod (object , method )
84+ methodCmd , err = newCommandFromMethod (object , method , methodValue , methodType )
8385 if err != nil {
8486 return
8587 }
8688 if nameSet .Contains (methodCmd .Name ) {
8789 err = gerror .Newf (
8890 `command name should be unique, found duplicated command name in method "%s"` ,
89- method . Type () .String (),
91+ methodType .String (),
9092 )
9193 return
9294 }
@@ -135,27 +137,23 @@ func methodToRootCmdWhenNameEqual(rootCmd *Command, methodCmd *Command) {
135137 }
136138}
137139
138- func newCommandFromObjectMeta (object interface {}) (command * Command , err error ) {
139- var (
140- metaData = gmeta .Data (object )
141- )
142- if len (metaData ) == 0 {
143- err = gerror .Newf (
144- `no meta data found in struct "%s"` ,
145- reflect .TypeOf (object ).String (),
146- )
147- return
148- }
140+ // The `object` is the Meta attribute from business object, and the `name` is the command name,
141+ // commonly from method name, which is used when no name tag is defined in Meta.
142+ func newCommandFromObjectMeta (object interface {}, name string ) (command * Command , err error ) {
143+ var metaData = gmeta .Data (object )
149144 if err = gconv .Scan (metaData , & command ); err != nil {
150145 return
151146 }
152147 // Name filed is necessary.
153148 if command .Name == "" {
154- err = gerror .Newf (
155- `command name cannot be empty, "name" tag not found in meta of struct "%s"` ,
156- reflect .TypeOf (object ).String (),
157- )
158- return
149+ if name == "" {
150+ err = gerror .Newf (
151+ `command name cannot be empty, "name" tag not found in meta of struct "%s"` ,
152+ reflect .TypeOf (object ).String (),
153+ )
154+ return
155+ }
156+ command .Name = name
159157 }
160158 if command .Description == "" {
161159 command .Description = metaData [tagNameDc ]
@@ -169,71 +167,70 @@ func newCommandFromObjectMeta(object interface{}) (command *Command, err error)
169167 return
170168}
171169
172- func newCommandFromMethod (object interface {}, method reflect.Value ) (command * Command , err error ) {
173- var (
174- reflectType = method .Type ()
175- )
170+ func newCommandFromMethod (
171+ object interface {}, method reflect.Method , methodValue reflect.Value , methodType reflect.Type ,
172+ ) (command * Command , err error ) {
176173 // Necessary validation for input/output parameters and naming.
177- if reflectType .NumIn () != 2 || reflectType .NumOut () != 2 {
178- if reflectType .PkgPath () != "" {
174+ if methodType .NumIn () != 2 || methodType .NumOut () != 2 {
175+ if methodType .PkgPath () != "" {
179176 err = gerror .NewCodef (
180177 gcode .CodeInvalidParameter ,
181178 `invalid command: %s.%s.%s defined as "%s", but "func(context.Context, Input)(Output, error)" is required` ,
182- reflectType .PkgPath (), reflect .TypeOf (object ).Name (), reflectType .Name (), reflectType .String (),
179+ methodType .PkgPath (), reflect .TypeOf (object ).Name (), methodType .Name (), methodType .String (),
183180 )
184181 } else {
185182 err = gerror .NewCodef (
186183 gcode .CodeInvalidParameter ,
187184 `invalid command: defined as "%s", but "func(context.Context, Input)(Output, error)" is required` ,
188- reflectType .String (),
185+ methodType .String (),
189186 )
190187 }
191188 return
192189 }
193- if reflectType .In (0 ).String () != "context.Context" {
190+ if methodType .In (0 ).String () != "context.Context" {
194191 err = gerror .NewCodef (
195192 gcode .CodeInvalidParameter ,
196193 `invalid command: defined as "%s", but the first input parameter should be type of "context.Context"` ,
197- reflectType .String (),
194+ methodType .String (),
198195 )
199196 return
200197 }
201- if reflectType .Out (1 ).String () != "error" {
198+ if methodType .Out (1 ).String () != "error" {
202199 err = gerror .NewCodef (
203200 gcode .CodeInvalidParameter ,
204201 `invalid command: defined as "%s", but the last output parameter should be type of "error"` ,
205- reflectType .String (),
202+ methodType .String (),
206203 )
207204 return
208205 }
209206 // The input struct should be named as `xxxInput`.
210- if ! gstr .HasSuffix (reflectType .In (1 ).String (), `Input` ) {
207+ if ! gstr .HasSuffix (methodType .In (1 ).String (), `Input` ) {
211208 err = gerror .NewCodef (
212209 gcode .CodeInvalidParameter ,
213210 `invalid struct naming for input: defined as "%s", but it should be named with "Input" suffix like "xxxInput"` ,
214- reflectType .In (1 ).String (),
211+ methodType .In (1 ).String (),
215212 )
216213 return
217214 }
218215 // The output struct should be named as `xxxOutput`.
219- if ! gstr .HasSuffix (reflectType .Out (0 ).String (), `Output` ) {
216+ if ! gstr .HasSuffix (methodType .Out (0 ).String (), `Output` ) {
220217 err = gerror .NewCodef (
221218 gcode .CodeInvalidParameter ,
222219 `invalid struct naming for output: defined as "%s", but it should be named with "Output" suffix like "xxxOutput"` ,
223- reflectType .Out (0 ).String (),
220+ methodType .Out (0 ).String (),
224221 )
225222 return
226223 }
227224
228225 var inputObject reflect.Value
229- if method . Type () .In (1 ).Kind () == reflect .Ptr {
230- inputObject = reflect .New (method . Type () .In (1 ).Elem ()).Elem ()
226+ if methodType .In (1 ).Kind () == reflect .Ptr {
227+ inputObject = reflect .New (methodType .In (1 ).Elem ()).Elem ()
231228 } else {
232- inputObject = reflect .New (method . Type () .In (1 )).Elem ()
229+ inputObject = reflect .New (methodType .In (1 )).Elem ()
233230 }
234231
235232 // Command creating.
236- if command , err = newCommandFromObjectMeta (inputObject .Interface ()); err != nil {
233+ if command , err = newCommandFromObjectMeta (inputObject .Interface (), method . Name ); err != nil {
237234 return
238235 }
239236
@@ -312,7 +309,7 @@ func newCommandFromMethod(object interface{}, method reflect.Value) (command *Co
312309 inputValues = append (inputValues , inputObject )
313310
314311 // Call handler with dynamic created parameter values.
315- results := method .Call (inputValues )
312+ results := methodValue .Call (inputValues )
316313 out = results [0 ].Interface ()
317314 if ! results [1 ].IsNil () {
318315 if v , ok := results [1 ].Interface ().(error ); ok {
0 commit comments