8181 setStr = flag .String ("set" , "" , "generate 'set' functions(union, intersection, difference, subset, superset) for user defined type. format- <StructName>:<FieldName> eg. Employee:Name, Employee:Salary" )
8282
8383 onlyList []string
84+
85+ switchTemplateDistinct = false
8486)
8587
8688func main () {
@@ -125,7 +127,10 @@ func main() {
125127 onlyList = strings .Split (* only , "," )
126128 onlyList = fp .MapStr (strings .TrimSpace , onlyList )
127129 }
128- generatedCode , err := generateFPCode (* pkgName , * types , * imports )
130+
131+ structToFieldsMap , structToFieldsMapUnExpected := findStructNamesAndFieldsGivenInGoGenerate ()
132+
133+ generatedCode , err := generateFPCode (* pkgName , * types , * imports , structToFieldsMapUnExpected )
129134 if err != nil {
130135 usage ()
131136 log .Fatalf ("Failed code generation: %v" , err )
@@ -173,7 +178,6 @@ import "sync"`, -1)
173178
174179 // Generate set and sort functions for all the types of struct
175180 if * sortStr == "" || * setStr == "" {
176- structToFieldsMap := findStructNamesAndFieldsGivenInGoGenerate ()
177181
178182 // 2nd condition is ignoring auto generation of sort functions for `all fp in 1 place strategy"
179183 // Can be done in future : change the logic to find struct name(employee.Teacher) current logic is not checking .
@@ -201,6 +205,9 @@ import "time"`, -1)
201205 }
202206 }
203207
208+ if switchTemplateDistinct {
209+ generatedCode = strings .Replace (generatedCode , `import _ "reflect"` , `import "reflect"` , - 1 )
210+ }
204211 f .Write ([]byte (generatedCode + "\n " + generatedCodeIO + "\n " + generatedCodeII + sortingCode + setCode ))
205212 defer f .Close ()
206213
@@ -220,14 +227,15 @@ func removeFirstPartOfDot(str string) string {
220227 return str
221228}
222229
223- func generateFPCode (pkg , dataTypes , imports string ) (string , error ) {
230+ func generateFPCode (pkg , dataTypes , imports string , structToFieldsMapUnexpected map [ string ][] string ) (string , error ) {
224231 basicTypes := "int, int64, int32, int16, int8, uint, uint64, uint32, uint16, uint8, float64, float32, string, bool"
225232 conditionalType := ""
226233 types := strings .Split (dataTypes , "," )
227234 types = fp .DistinctStrIgnoreCase (types )
228235
229236 template := "// Code generated by 'gofp'. DO NOT EDIT.\n "
230237 template += "package <PACKAGE>\n "
238+ template += "import _ \" reflect\" \n "
231239 template += "import \" sync\" \n "
232240
233241 if imports != "" {
@@ -255,6 +263,9 @@ func generateFPCode(pkg, dataTypes, imports string) (string, error) {
255263
256264 template = r .Replace (template )
257265
266+ // it collects info of members of struct other than basic types
267+ unexpectedFieldsForDistinct := structToFieldsMapUnexpected [t ]
268+
258269 if len (onlyList ) > 0 {
259270 // Always include these functions
260271
@@ -474,7 +485,30 @@ func generateFPCode(pkg, dataTypes, imports string) (string, error) {
474485 template = r2 .Replace (template )
475486 }
476487
477- /*
488+ if len (unexpectedFieldsForDistinct ) > 1 {
489+ switchTemplateDistinct = true
490+
491+ if fp .ExistsStrIgnoreCase ("DistinctP" , onlyList ) {
492+ template += basic .DistinctP2 ()
493+ template = r2 .Replace (template )
494+ }
495+
496+ if fp .ExistsStrIgnoreCase ("DistinctPPtr" , onlyList ) {
497+ template += basic .DistinctPPtr2 ()
498+ template = r2 .Replace (template )
499+ }
500+
501+ if fp .ExistsStrIgnoreCase ("Distinct" , onlyList ) {
502+ template += basic .Distinct2 ()
503+ template = r2 .Replace (template )
504+ }
505+
506+ if fp .ExistsStrIgnoreCase ("DistinctPtr" , onlyList ) {
507+ template += basic .DistinctPtr2 ()
508+ template = r2 .Replace (template )
509+ }
510+
511+ } else {
478512 if fp .ExistsStrIgnoreCase ("DistinctP" , onlyList ) {
479513 template += basic .DistinctP ()
480514 template = r2 .Replace (template )
@@ -494,8 +528,7 @@ func generateFPCode(pkg, dataTypes, imports string) (string, error) {
494528 template += basic .DistinctPtr ()
495529 template = r2 .Replace (template )
496530 }
497-
498- */
531+ }
499532
500533 } else {
501534 template += template2 .Map ()
@@ -641,7 +674,23 @@ func generateFPCode(pkg, dataTypes, imports string) (string, error) {
641674
642675 template += basic .TakePtr ()
643676 template = r2 .Replace (template )
644- /*
677+
678+ if len (unexpectedFieldsForDistinct ) > 1 {
679+ switchTemplateDistinct = true
680+
681+ template += basic .DistinctP2 ()
682+ template = r2 .Replace (template )
683+
684+ template += basic .DistinctPPtr2 ()
685+ template = r2 .Replace (template )
686+
687+ template += basic .Distinct2 ()
688+ template = r2 .Replace (template )
689+
690+ template += basic .DistinctPtr2 ()
691+ template = r2 .Replace (template )
692+
693+ } else {
645694 template += basic .DistinctP ()
646695 template = r2 .Replace (template )
647696
@@ -653,10 +702,8 @@ func generateFPCode(pkg, dataTypes, imports string) (string, error) {
653702
654703 template += basic .DistinctPtr ()
655704 template = r2 .Replace (template )
656-
657- */
705+ }
658706 }
659-
660707 }
661708 return template , nil
662709}
@@ -1128,7 +1175,7 @@ func listDir(dirName string) ([]string, error) {
11281175 return files , nil
11291176}
11301177
1131- func findStructNamesAndFieldsGivenInGoGenerate () map [string ][]string {
1178+ func findStructNamesAndFieldsGivenInGoGenerate () ( map [string ][]string , map [ string ][] string ) {
11321179 allTypesInGoGenerate := strings .Split (* types , "," )
11331180
11341181 isUserDefinedType := func (dataType string ) bool {
@@ -1141,6 +1188,7 @@ func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
11411188 userDefinedTypesInGoGenerate := fp .MapStr (strings .TrimSpace , fp .FilterStr (isUserDefinedType , allTypesInGoGenerate ))
11421189
11431190 structToFieldsMap := make (map [string ][]string , len (userDefinedTypesInGoGenerate ))
1191+ structToFieldsMapUnExpected := make (map [string ][]string , len (userDefinedTypesInGoGenerate ))
11441192 structToFieldsMapIndex := 0
11451193
11461194 path , err := os .Getwd ()
@@ -1150,7 +1198,7 @@ func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
11501198 files , err := listDir (path )
11511199 if err != nil {
11521200 fmt .Printf ("\n error scanning current folder=%v, error=%v. sort and set methods will be skipped" , path , err )
1153- return nil
1201+ return nil , nil
11541202 }
11551203
11561204 onlyGoFiles := fp .FilterStr (func (str string ) bool {
@@ -1167,14 +1215,15 @@ func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
11671215 file , err := os .Open (fileStr )
11681216 if err != nil {
11691217 fmt .Printf ("\n error reading file=%s to generate sort and set methods. skipping set and sort functions" , fileStr )
1170- return nil
1218+ return nil , nil
11711219 }
11721220 defer file .Close ()
11731221
11741222 scanner := bufio .NewScanner (file )
11751223 packageFound := false
11761224 startCollectingStructInfo := false
11771225 var structFields []string
1226+ var structFieldsUnExpected []string
11781227
11791228 for scanner .Scan () {
11801229 txtLine := scanner .Text ()
@@ -1199,9 +1248,15 @@ func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
11991248 for i , v := range structFields {
12001249 newStructFieldsArr [i ] = v
12011250 }
1251+
1252+ newStructFieldsArrUnExpected := make ([]string , len (structFieldsUnExpected ))
1253+ copy (newStructFieldsArrUnExpected , structFieldsUnExpected )
1254+
12021255 structToFieldsMap [userDefinedTypesInGoGenerate [structToFieldsMapIndex ]] = newStructFieldsArr
1256+ structToFieldsMapUnExpected [userDefinedTypesInGoGenerate [structToFieldsMapIndex ]] = newStructFieldsArrUnExpected
12031257 structToFieldsMapIndex ++
12041258 structFields = make ([]string , 0 )
1259+ structFieldsUnExpected = make ([]string , 0 )
12051260 }
12061261
12071262 if startCollectingStructInfo {
@@ -1212,6 +1267,8 @@ func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
12121267 switch dataType {
12131268 case "int" , "int64" , "int32" , "int16" , "int8" , "uint" , "uint64" , "uint32" , "uint16" , "uint8" , "float64" , "float32" , "string" , "time.Time" , "*time.Time" , "*int" , "*int64" , "*int32" , "*int16" , "*int8" , "*uint" , "*uint64" , "*uint32" , "*uint16" , "*uint8" , "*float64" , "*float32" , "*string" :
12141269 structFields = append (structFields , field + " " + dataType )
1270+ default :
1271+ structFieldsUnExpected = append (structFieldsUnExpected , field + " " + dataType )
12151272 }
12161273 }
12171274 }
@@ -1220,108 +1277,9 @@ func findStructNamesAndFieldsGivenInGoGenerate() map[string][]string {
12201277
12211278 if err := scanner .Err (); err != nil {
12221279 fmt .Printf ("\n error scanning data from file %s. skipping generation of sort and set functions" , fileStr )
1223- return nil
1224- }
1225- }
1226-
1227- return structToFieldsMap
1228- }
1229-
1230- func allFeildsInStruct () map [string ][]string {
1231- allTypesInGoGenerate := strings .Split (* types , "," )
1232-
1233- isUserDefinedType := func (dataType string ) bool {
1234- switch strings .ToLower (strings .TrimSpace (dataType )) {
1235- case "int" , "int64" , "int32" , "int16" , "int8" , "uint" , "uint64" , "uint32" , "uint16" , "uint8" , "float64" , "float32" , "string" , "bool" :
1236- return false
1237- }
1238- return true
1239- }
1240- userDefinedTypesInGoGenerate := fp .MapStr (strings .TrimSpace , fp .FilterStr (isUserDefinedType , allTypesInGoGenerate ))
1241-
1242- structToFieldsMap := make (map [string ][]string , len (userDefinedTypesInGoGenerate ))
1243- structToFieldsMapIndex := 0
1244-
1245- path , err := os .Getwd ()
1246- if err != nil {
1247- fmt .Println (err )
1248- }
1249- files , err := listDir (path )
1250- if err != nil {
1251- fmt .Printf ("\n error scanning current folder=%v, error=%v. sort and set methods will be skipped" , path , err )
1252- return nil
1253- }
1254-
1255- onlyGoFiles := fp .FilterStr (func (str string ) bool {
1256- return strings .Contains (str , ".go" )
1257- }, files )
1258-
1259- totalStructCount := 0
1260- for _ , fileStr := range onlyGoFiles {
1261-
1262- if totalStructCount == len (userDefinedTypesInGoGenerate ) {
1263- break
1264- }
1265-
1266- file , err := os .Open (fileStr )
1267- if err != nil {
1268- fmt .Printf ("\n error reading file=%s to generate sort and set methods. skipping set and sort functions" , fileStr )
1269- return nil
1270- }
1271- defer file .Close ()
1272-
1273- scanner := bufio .NewScanner (file )
1274- packageFound := false
1275- startCollectingStructInfo := false
1276- var structFields []string
1277-
1278- for scanner .Scan () {
1279- txtLine := scanner .Text ()
1280- if len (txtLine ) > 0 && strings .Contains (txtLine , * pkgName ) {
1281- packageFound = true
1282- }
1283- // reading lines of file of package mentioned in go:generate
1284- if packageFound {
1285-
1286- words := strings .Fields (txtLine )
1287-
1288- // Found struct
1289- if len (words ) == 4 && strings .Contains (words [0 ], "type" ) && fp .ExistsStr (words [1 ], userDefinedTypesInGoGenerate ) && strings .Contains (words [2 ], "struct" ) && strings .Contains (words [3 ], "{" ) {
1290- startCollectingStructInfo = true
1291- totalStructCount ++
1292- }
1293-
1294- if startCollectingStructInfo && strings .TrimSpace (txtLine ) == "}" {
1295- startCollectingStructInfo = false
1296-
1297- newStructFieldsArr := make ([]string , len (structFields ))
1298- for i , v := range structFields {
1299- newStructFieldsArr [i ] = v
1300- }
1301- structToFieldsMap [userDefinedTypesInGoGenerate [structToFieldsMapIndex ]] = newStructFieldsArr
1302- structToFieldsMapIndex ++
1303- structFields = make ([]string , 0 )
1304- }
1305-
1306- if startCollectingStructInfo {
1307- if len (words ) >= 2 {
1308- field := strings .TrimSpace (words [0 ])
1309- dataType := strings .TrimSpace (words [1 ])
1310-
1311- //switch dataType {
1312- //case "int", "int64", "int32", "int16", "int8", "uint", "uint64", "uint32", "uint16", "uint8", "float64", "float32", "string", "time.Time", "*time.Time", "*int", "*int64", "*int32", "*int16", "*int8", "*uint", "*uint64", "*uint32", "*uint16", "*uint8", "*float64", "*float32", "*string":
1313- structFields = append (structFields , field + " " + dataType )
1314- //}
1315- }
1316- }
1317- }
1318- }
1319-
1320- if err := scanner .Err (); err != nil {
1321- fmt .Printf ("\n error scanning data from file %s. skipping generation of sort and set functions" , fileStr )
1322- return nil
1280+ return nil , nil
13231281 }
13241282 }
13251283
1326- return structToFieldsMap
1284+ return structToFieldsMap , structToFieldsMapUnExpected
13271285}
0 commit comments