{"id":34629033,"url":"https://github.com/sublee/convgen","last_synced_at":"2026-03-15T01:43:52.772Z","repository":{"id":318706162,"uuid":"843649537","full_name":"sublee/convgen","owner":"sublee","description":"Refactor-safe type conversion codegen for Go","archived":false,"fork":false,"pushed_at":"2025-10-18T05:48:43.000Z","size":1538,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-10-19T03:37:20.250Z","etag":null,"topics":["codegen","converter"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sublee.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2024-08-17T02:28:37.000Z","updated_at":"2025-10-18T05:48:47.000Z","dependencies_parsed_at":"2025-10-09T16:03:22.624Z","dependency_job_id":"0b692642-3ca5-4713-adf2-538d58eb6ccf","html_url":"https://github.com/sublee/convgen","commit_stats":null,"previous_names":["sublee/convgen"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/sublee/convgen","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sublee%2Fconvgen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sublee%2Fconvgen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sublee%2Fconvgen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sublee%2Fconvgen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sublee","download_url":"https://codeload.github.com/sublee/convgen/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sublee%2Fconvgen/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28004716,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-12-24T02:00:07.193Z","response_time":83,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["codegen","converter"],"created_at":"2025-12-24T16:33:11.760Z","updated_at":"2025-12-24T16:33:16.743Z","avatar_url":"https://github.com/sublee.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003e [!WARNING]\n\u003e Convgen is in early development. If you have any feedback, please open an\n\u003e issue.\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"assets/convgen.png\" alt=\"Convgen Logo\" width=\"320\" /\u003e\n\u003c/p\u003e\n\n\u003ch1 align=\"center\"\u003eConvgen\u003c/h1\u003e\n\u003cp align=\"center\"\u003e\u003ci\u003eRefactor-safe type conversion codegen for Go\u003c/i\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://github.com/sublee/convgen/actions/workflows/ci.yaml\"\u003e\u003cimg src=\"https://github.com/sublee/convgen/actions/workflows/ci.yaml/badge.svg\" alt=\"CI\"\u003e\u003c/a\u003e\n\u003ca href=\"https://pkg.go.dev/github.com/sublee/convgen\"\u003e\u003cimg src=\"https://pkg.go.dev/badge/github.com/sublee/convgen.svg\" alt=\"Go Reference\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\nConvgen generates type-to-type conversion code for Go automatically. It's\n**type-safe**, **refactorable**, and designed to detect every mismatch with\n**detailed diagnostics**.\n\n```go\n// source:\nvar EncodeUser = convgen.Struct[User, api.User](nil,\n    convgen.RenameReplace(\"\", \"\", \"Id\", \"ID\"), // Replace Id with ID in output types before matching\n    convgen.Match(User{}.Name, api.User{}.Username), // Explicit field matching\n)\n```\n\n```go\n// generated: (simplified)\nfunc EncodeUser(in User) (out api.User) {\n    out.Id = in.ID\n    out.Username = in.Name\n    out.Email = in.Email\n    return\n}\n```\n\n## Features\n\n- **Automatic type conversions by codegen**  \n  Convgen generates conversion code at compile time, so there's no runtime\n  reflection overhead. It supports conversions between structs, unions\n  (interfaces with multiple implementations), and enums (const groups),\n  automatically matching fields, implementations, and members by name.\n  \n  ```go\n  convgen.Struct[User, api.User]      // func(User) api.User\n  convgen.StructErr[User, api.User]   // func(User) (api.User, error)\n  convgen.Union[Job, api.Job]         // func(Job) api.Job -- type UploadJob, type OrderJob, ...\n  convgen.UnionErr[Job, api.Job]      // func(Job) (api.Job, error)\n  convgen.Enum[Status, api.Status]    // func(Status) api.Status -- const StatusTodo, const StatusPending, ...\n  convgen.EnumErr[Status, api.Status] // func(Status) (api.Status, error)\n  ```\n\n- **Refactor-safe configuration**  \n  All options are validated at compile time — no struct tags, strings, or\n  comment-based directives.\n\n  ```go\n  // Custom conversion functions must be reachable.\n  convgen.ImportFunc(strconv.Itoa)\n\n  // If User{}.Name is renamed by a refactoring tool,\n  // this directive will be updated accordingly.\n  convgen.Match(User{}.Name, api.User{}.Username)\n  ```\n\n- **Batched diagnostics**  \n  *All* matching and conversion errors in a single pass are reported together,\n  so you can fix everything at once instead of stopping at the first error. In\n  addition, Convgen provides [Lint](#lint) support for real-time feedback during\n  development.\n\n  ```\n  main.go:10:10: invalid match between User and api.User\n      ok:   Name    -\u003e Username // forced at main.go:12:2\n      ok:   ID      -\u003e ID [Id]\n      ok:   GroupID -\u003e GroupID [GroupId]\n      FAIL: ?       -\u003e Email // missing\n      FAIL: EMail   -\u003e ?     // missing\n  ```\n\n## Motivation\n\nConvgen is inspired by both [goverter](https://github.com/jmattheis/goverter)\nand [Wire](https://github.com/google/wire). While goverter is powerful for\ngenerating type conversion code, it relies on comment-based directives that are\nnot validated at compile time. Moreover, because it stops at the first error,\nrefactoring becomes difficult when target types change. In contrast, Wire offers\ntype-safe configuration and detailed diagnostics, but focuses on dependency\ninjection.\n\nConvgen combines the best of both worlds, bringing **refactor-safe configuration**\nand **batched diagnostics** to **automatic type conversions by codegen**.\n\nTo compare Convgen and goverter, see [cmd/vs-goverter](cmd/vs-goverter)\ndirectory.\n\n## Quick Start\n\n1. Install Convgen:\n\n    ```bash\n    go install github.com/sublee/convgen\n    ```\n\n2. Add a build constraint to files containing Convgen directives:\n\n    ```go\n    //go:build convgen\n    ```\n\n3. Declare your conversions:\n\n    ```go\n    var EncodeUser = convgen.Struct[User, api.User](nil)\n    ```\n\n4. Run the generator:\n\n    ```bash\n    convgen ./...\n    ```\n\n5. Convgen generates a `convgen_gen.go` file by copying your `//go:build convgen`\n   files and rewriting Convgen directives:\n\n    ```go\n    func EncodeUser(in User) (out api.User) {\n        out.Name = in.Name\n        out.Email = in.Email\n        return\n    }\n    ```\n\n## Lint\n\nConvgen provides a [golangci-lint](https://github.com/golangci/golangci-lint)\nplugin that validates Convgen directives during development inside your IDE.\n\nIt's not an official plugin, so you need to build it manually:\n\n```bash\nmake golangci-lint-convgen\n```\n\nThen, add the following configuration to your `.golangci.yaml`. Because Convgen\ndirectives are only valid when the `convgen` build tag is set, make sure to\ninclude it under the `run.build-tags` section:\n\n```yaml\nversion: \"2\"\n\nrun:\n  build-tags:\n    - convgen\n\nlinters:\n  settings:\n    custom:\n      convgen:\n        type: module\n```\n\nNow the `golangci-lint-convgen` binary can validate Convgen directives in your\nproject. To make this process seamless in your IDE, you can configure it as the\ndefault linter. For Visual Studio Code, add the following to your settings:\n\n```json\n{\n  \"go.lintTool\": \"golangci-lint-v2\",\n  \"go.lintFlags\": [\"--build-tags=convgen\"],\n  \"go.alternateTools\": {\n    \"golangci-lint-v2\": \"/path/to/golangci-lint-convgen\",\n  }\n}\n```\n\nWith this setup, your Convgen directives will be validated in real time as you\ncode.\n\n## License\n\nMIT License — see [LICENSE](LICENSE) for details.\n\n## Author\n\n[Heungsub Lee](https://subl.ee/), with assistance from ChatGPT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsublee%2Fconvgen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsublee%2Fconvgen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsublee%2Fconvgen/lists"}