@@ -55,12 +55,41 @@ func (f *FlagSetFiller) Fill(flagSet *flag.FlagSet, from interface{}) error {
5555 }
5656}
5757
58+ // this is a list of supported struct, like time.Time, that walkFields() won't walk into,
59+ // the key is the is string returned by the getTypeName(<struct_type>),
60+ // each supported struct need to be added in this map in init()
61+ var supportedStructList = make (map [string ]struct {})
62+
63+ func isSupportedStruct (name string ) bool {
64+ _ , ok := supportedStructList [name ]
65+ return ok
66+ }
67+
68+ func getTypeName (t reflect.Type ) string {
69+ return t .PkgPath () + "." + t .Name ()
70+ }
71+
5872func (f * FlagSetFiller ) walkFields (flagSet * flag.FlagSet , prefix string ,
5973 structVal reflect.Value , structType reflect.Type ) error {
6074
6175 if prefix != "" {
6276 prefix += "-"
6377 }
78+ handleDefault := func (field reflect.StructField , fieldValue reflect.Value ) error {
79+ addr := fieldValue .Addr ()
80+ // make sure it is exported/public
81+ ftype := field .Type
82+ if field .Type .Kind () == reflect .Ptr {
83+ ftype = field .Type .Elem ()
84+ }
85+ if addr .CanInterface () {
86+ err := f .processField (flagSet , addr .Interface (), prefix + field .Name , ftype , field .Tag )
87+ if err != nil {
88+ return fmt .Errorf ("failed to process %s of %s: %w" , field .Name , structType .String (), err )
89+ }
90+ }
91+ return nil
92+ }
6493 for i := 0 ; i < structVal .NumField (); i ++ {
6594 field := structType .Field (i )
6695 fieldValue := structVal .Field (i )
@@ -73,17 +102,33 @@ func (f *FlagSetFiller) walkFields(flagSet *flag.FlagSet, prefix string,
73102
74103 switch field .Type .Kind () {
75104 case reflect .Struct :
105+ fieldTypeName := getTypeName (field .Type )
106+ if isSupportedStruct (fieldTypeName ) {
107+ err := handleDefault (field , fieldValue )
108+ if err != nil {
109+ return err
110+ }
111+ continue
112+ }
76113 err := f .walkFields (flagSet , prefix + field .Name , fieldValue , field .Type )
77114 if err != nil {
78115 return fmt .Errorf ("failed to process %s of %s: %w" , field .Name , structType .String (), err )
79116 }
80117
81118 case reflect .Ptr :
82119 if fieldValue .CanSet () && field .Type .Elem ().Kind () == reflect .Struct {
120+ fieldTypeName := getTypeName (field .Type .Elem ())
83121 // fill the pointer with a new struct of their type if it is nil
84122 if fieldValue .IsNil () {
85123 fieldValue .Set (reflect .New (field .Type .Elem ()))
86124 }
125+ if isSupportedStruct (fieldTypeName ) {
126+ err := handleDefault (field , fieldValue .Elem ())
127+ if err != nil {
128+ return err
129+ }
130+ continue
131+ }
87132
88133 err := f .walkFields (flagSet , field .Name , fieldValue .Elem (), field .Type .Elem ())
89134 if err != nil {
@@ -92,13 +137,9 @@ func (f *FlagSetFiller) walkFields(flagSet *flag.FlagSet, prefix string,
92137 }
93138
94139 default :
95- addr := fieldValue .Addr ()
96- // make sure it is exported/public
97- if addr .CanInterface () {
98- err := f .processField (flagSet , addr .Interface (), prefix + field .Name , field .Type , field .Tag )
99- if err != nil {
100- return fmt .Errorf ("failed to process %s of %s: %w" , field .Name , structType .String (), err )
101- }
140+ err := handleDefault (field , fieldValue )
141+ if err != nil {
142+ return err
102143 }
103144 }
104145 }
@@ -139,8 +180,21 @@ func (f *FlagSetFiller) processField(flagSet *flag.FlagSet, fieldRef interface{}
139180 } else {
140181 renamed = f .options .renameLongName (name )
141182 }
142-
183+ typeName := getTypeName ( t )
143184 switch {
185+ //check the typeName
186+ case typeName == "net.IP" :
187+ f .processIP (fieldRef , hasDefaultTag , tagDefault , flagSet , renamed , usage , aliases )
188+ case typeName == "net.IPNet" :
189+ f .processIPNet (fieldRef , hasDefaultTag , tagDefault , flagSet , renamed , usage , aliases )
190+ case typeName == "net.HardwareAddr" :
191+ f .processMAC (fieldRef , hasDefaultTag , tagDefault , flagSet , renamed , usage , aliases )
192+
193+ case typeName == "time.Time" :
194+ layoutStr , _ := tag .Lookup ("layout" )
195+ f .processTime (fieldRef , hasDefaultTag , tagDefault , flagSet , renamed , usage , aliases , layoutStr )
196+ //end of check typeName
197+
144198 case t .Kind () == reflect .String :
145199 f .processString (fieldRef , hasDefaultTag , tagDefault , flagSet , renamed , usage , aliases )
146200
0 commit comments