11# Convgen
22
3- ![ Convgen Logo] ( assets/convgen.jpg )]
3+ <p align =" center " >
4+ <img src =" assets/convgen.jpg " alt =" Convgen Logo " width =" 320 " />
5+ </p >
46
57Convgen generates ** type-to-type conversion code** for Go with ** type-safe
68configuration** and ** detailed diagnostics** .
79
810``` go
911// go:build convgen
12+
1013var EncodeUser = convgen.Struct [User, api.User ](nil ,
1114 convgen.RenameReplace (" " , " " , " Id" , " ID" ), // Replace Id with ID in output types before matching
1215 convgen.Match (User{}.Name , api.User {}.Username ), // Explicit field matching
@@ -17,13 +20,42 @@ var EncodeUser = convgen.Struct[User, api.User](nil,
1720
1821- ** Struct, Union, and Enum conversions**
1922 Automatically matches fields, implementations, and members by name.
23+
24+ ``` go
25+ convgen.Struct [User, api.User ] // func(User) api.User
26+ convgen.StructErr [User, api.User ] // func(User) (api.User, error)
27+ convgen.Union [Job, api.Job ] // func(Job) api.Job -- type UploadJob, type OrderJob, ...
28+ convgen.UnionErr [Job, api.Job ] // func(Job) (api.Job, error)
29+ convgen.Enum [Status, api.Status ] // func(Status) api.Status -- const StatusTodo, const StatusPending, ...
30+ convgen.EnumErr [Status, api.Status ] // func(Status) (api.Status, error)
31+ ```
32+
2033- ** Type-safe configuration**
2134 All options are validated at compile time — no reflection, tags, string, or
2235 comment-based directives.
36+
37+ ``` go
38+ // Custom conversion functions must be reachable.
39+ convgen.ImportFunc (strconv.Itoa )
40+
41+ // If User{}.Name is renamed by a refactoring tool,
42+ // this directive will be updated accordingly.
43+ convgen.Match (User{}.Name , api.User {}.Username )
44+ ```
45+
2346- ** Detailed diagnostics**
2447 * All* matching and conversion errors in a single pass are reported together,
2548 so you can fix everything at once instead of stopping at the first error.
2649
50+ ```
51+ main.go:10:10: invalid match between User and api.User
52+ ok: Name -> Username // forced at main.go:12:2
53+ ok: ID -> ID [Id]
54+ ok: GroupID -> GroupID [GroupId]
55+ FAIL: ? -> Email // missing
56+ FAIL: EMail -> ? // missing
57+ ```
58+
2759## Motivation
2860
2961Convgen is inspired by both [ goverter] ( https://github.com/jmattheis/goverter )
@@ -36,104 +68,47 @@ injection. Convgen combines the best of both worlds, bringing **type-safe
3668configuration** and ** comprehensive diagnostics** to
3769** type conversion code generation** .
3870
39- ## Installation
40-
41- ``` bash
42- go install github.com/sublee/convgen
43- ```
44-
4571## Quick Start
4672
47- 1 . Add a build constraint to files containing Convgen directives:
48-
49- ``` go
50- // go:build convgen
51- ```
52-
53- 2 . Declare your conversions:
54-
55- ``` go
56- // go:build convgen
57- package main
58-
59- import " github.com/sublee/convgen"
60-
61- // Simple struct conversion
62- var EncodeUser = convgen.Struct [User, api.User ](nil )
63- ```
64-
65- 3 . Run the generator:
66-
67- ``` bash
68- go run github.com/sublee/convgen/cmd/convgen ./...
69- ```
70-
71- This generates ` convgen_gen.go ` with the implementation:
72-
73- ``` go
74- func EncodeUser (in User ) (out api .User ) {
75- out.Name = in.Name
76- out.Email = in.Email
77- return
78- }
79- ```
80-
81- ## Example
73+ 1 . Install Convgen:
8274
83- ``` go
84- // go:build convgen
75+ ``` bash
76+ go install github.com/sublee/convgen
77+ ```
8578
86- package main
79+ 2. Add a build constraint to files containing Convgen directives:
8780
88- import " github.com/sublee/convgen"
81+ ` ` ` go
82+ //go:build convgen
83+ ` ` `
8984
90- // Create a module with shared configuration
91- var mod = convgen.Module (
92- convgen.RenameToLower (true , true ),
93- )
85+ 3. Declare your conversions:
9486
95- // Declare conversions
96- var (
97- EncodeUser = convgen.Struct [User, api.User ](mod,
98- convgen.Match (User{}.ID , api.User {}.Id ), // explicit field matching
99- )
100- EncodeRole = convgen.Enum [Role, api.Role ](mod,
101- api.ROLE_UNSPECIFIED , // default value
102- convgen.RenameTrimCommonPrefix (true , true ),
103- )
104- )
105- ```
87+ ` ` ` go
88+ var EncodeUser = convgen.Struct[User, api.User](nil)
89+ ` ` `
10690
107- ## Configuration
91+ 4. Run the generator:
10892
109- When field mappings are ambiguous, Convgen provides detailed diagnostics:
93+ ` ` ` bash
94+ convgen ./...
95+ ` ` `
11096
111- ```
112- main.go:10:10: invalid match between User and api.User
113- FAIL: ID -> ? // missing
114- FAIL: ? -> Id // missing
115- ```
97+ 5. Convgen generates a ` convgen_gen.go` file by copying your ` //go:build convgen`
98+ files and rewriting Convgen directives:
11699
117- Resolve with renaming rules:
118-
119- ``` go
120- var EncodeUser = convgen.Struct [User, api.User ](nil ,
121- convgen.RenameToLower (true , true ),
122- )
123- ```
124-
125- Or explicit matching:
126-
127- ``` go
128- var EncodeUser = convgen.Struct [User, api.User ](nil ,
129- convgen.Match (User{}.ID , api.User {}.Id ),
130- )
131- ```
100+ ` ` ` go
101+ func EncodeUser(in User) (out api.User) {
102+ out.Name = in.Name
103+ out.Email = in.Email
104+ return
105+ }
106+ ` ` `
132107
133108# # License
134109
135- MIT License - see [ LICENSE] ( LICENSE ) for details.
110+ MIT License -- see [LICENSE](LICENSE) for details.
136111
137112# # Author
138113
139- Heungsub Lee
114+ [ Heungsub Lee](https://subl.ee/) and ChatGPT
0 commit comments