https://github.com/fuji8/gotypeconverter
Go tool to generate functions that converts two structurally different types
https://github.com/fuji8/gotypeconverter
generator go golang tool
Last synced: 9 months ago
JSON representation
Go tool to generate functions that converts two structurally different types
- Host: GitHub
- URL: https://github.com/fuji8/gotypeconverter
- Owner: fuji8
- License: apache-2.0
- Created: 2020-12-29T20:23:53.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2025-01-05T07:50:09.000Z (over 1 year ago)
- Last Synced: 2025-04-09T21:51:24.809Z (about 1 year ago)
- Topics: generator, go, golang, tool
- Language: Go
- Homepage:
- Size: 265 KB
- Stars: 3
- Watchers: 1
- Forks: 0
- Open Issues: 12
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# gotypeconverter [](https://github.com/fuji8/gotypeconverter/actions) [](https://github.com/fuji8/gotypeconverter/actions/workflows/codeql-analysis.yml)
gotypeconverter generates a function that converts two structurally different types.
[日本語(原本)](https://github.com/fuji8/gotypeconverter/blob/main/README_JA.md)
## Install
```shell
go install github.com/fuji8/gotypeconverter/cmd/gotypeconverter
```
## Usage
```shell
> gotypeconverter
gotypeconverter: gotypeconverter generates a function that converts two different named types.
Usage: gotypeconverter [-flag] [package]
Flags:
-d string
destination type
-o string
output file; if nil, output stdout
-pkg string
output package; if nil, the directoryName and packageName must be same and will be used
-s string
source type
-structTag string
(default "cvt")
```
## Caution
Make sure the directory name and package name are the same. If they cannot be the same, make the module name and package name the same and specify with -pkg.
## Examples
see [testdata](https://github.com/fuji8/gotypeconverter/tree/main/testdata/src)
### Basic example
```go basic.go
package main
type basicSrc struct {
foo int
bar float64
x string
y string
}
type basicDst struct {
foo int
bar float32
x string
z string `cvt:"y"`
}
```
```shell
> gotypeconverter -s basicSrc -d basicDst -pkg main .
// Code generated by gotypeconverter; DO NOT EDIT.
package main
func ConvertbasicSrcTobasicDst(src basicSrc) (dst basicDst) {
dst.foo = src.foo
dst.x = src.x
dst.z = src.y
return
}
```
### Normal example
```go normal.go
package normal
type e struct {
e bool
m string
x int
members []uint8
}
type ug struct {
uaiueo uint8
gaaaa uint8
}
type normalSrc struct {
x struct {
A int
B bool
C string
D string
}
y int
z float64
m string
members []ug
}
type normalDst struct {
e
x string
y int
z float64
}
```
```bash
> gotypeconverter -s normalSrc -d normalDst .
// Code generated by gotypeconverter; DO NOT EDIT.
package normal
func ConvertnormalSrcTonormalDst(src normalSrc) (dst normalDst) {
dst.e.m = src.m
dst.e.x = src.x.A
dst.e.members = make([]uint8, len(src.members))
for i := range src.members {
dst.e.members[i] = src.members[i].uaiueo
}
dst.x = src.x.C
dst.y = src.y
dst.z = src.z
return
}
```
## Conversion rules
WIP
https://github.com/fuji8/gotypeconverter/blob/v0.1.0/gotypeconverter.go#L449-L543
```go
switch dstT := dst.(type) {
case *types.Basic:
switch srcT := src.(type) {
case *types.Basic:
case *types.Named:
return fm.otherAndNamed(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Slice:
return fm.otherAndSlice(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Struct:
return fm.otherAndStruct(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Pointer:
return fm.otherAndPointer(dst, srcT, dstSelector, srcSelector, index, history)
default:
}
case *types.Named:
switch srcT := src.(type) {
case *types.Basic:
return fm.namedAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Named:
return fm.namedAndNamed(dstT, srcT, dstSelector, srcSelector, index, history)
case *types.Slice:
return fm.namedAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Struct:
return fm.namedAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Pointer:
return fm.namedAndOther(dstT, src, dstSelector, srcSelector, index, history)
default:
return fm.namedAndOther(dstT, src, dstSelector, srcSelector, index, history)
}
case *types.Slice:
switch srcT := src.(type) {
case *types.Basic:
return fm.sliceAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Named:
return fm.otherAndNamed(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Slice:
return fm.sliceAndSlice(dstT, srcT, dstSelector, srcSelector, index, history)
case *types.Struct:
return fm.sliceAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Pointer:
return fm.otherAndPointer(dst, srcT, dstSelector, srcSelector, index, history)
default:
return fm.sliceAndOther(dstT, src, dstSelector, srcSelector, index, history)
}
case *types.Struct:
switch srcT := src.(type) {
case *types.Basic:
return fm.structAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Named:
return fm.otherAndNamed(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Slice:
return fm.otherAndSlice(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Struct:
return fm.structAndStruct(dstT, srcT, dstSelector, srcSelector, index, history) ||
fm.structAndOther(dstT, src, dstSelector, srcSelector, index, history) ||
fm.otherAndStruct(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Pointer:
return fm.otherAndPointer(dst, srcT, dstSelector, srcSelector, index, history)
default:
return fm.structAndOther(dstT, src, dstSelector, srcSelector, index, history)
}
case *types.Pointer:
switch srcT := src.(type) {
case *types.Basic:
case *types.Named:
return fm.pointerAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Slice:
return fm.pointerAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Struct:
return fm.pointerAndOther(dstT, src, dstSelector, srcSelector, index, history)
case *types.Pointer:
return fm.otherAndPointer(dst, srcT, dstSelector, srcSelector, index, history)
default:
return fm.pointerAndOther(dstT, src, dstSelector, srcSelector, index, history)
}
default:
switch srcT := src.(type) {
case *types.Basic:
case *types.Named:
return fm.otherAndNamed(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Slice:
return fm.otherAndSlice(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Struct:
return fm.otherAndStruct(dst, srcT, dstSelector, srcSelector, index, history)
case *types.Pointer:
return fm.otherAndPointer(dst, srcT, dstSelector, srcSelector, index, history)
default:
}
}
```