すでに世の中にありそうな気がするけど作りました。もうあったらそっちを使いたいので教えてください。READMEがぜんぜん整備されていないので手があいたときになんとかしたい。
2023/6/19 11:53 追記
社内でcopierを教えてもらいました。
やりたいことにはおおむね合っていそうで機能も揃っていそうな印象? ただ、静的に変換できることが分かっているstructなら静的に (エラーなしで) 変換されたいかな〜という気持ちがあります。
モチベーション
以下のような2つのstructがあったとします。CreatedAt
UpdatedAt
はDB上でしか管理しないフィールドなので *foo.FooModel
上に対応するフィールドがないとしましょう。
package foo type FooModel struct { Id string Name string Age int }
package bar type BarModel struct { Id string Name string Age int CreatedAt time.Time UpdatedAt time.Time }
*bar.BarModel
を *foo.FooModel
に変換する関数あるいはメソッドを生やすことを考えると、フィールド名が一致するフィールドをマッピングして新しいstructを作って返せばよいだけなので、とくに難しいことはありません。
しかしながら、後からフィールドを足したり、そもそもフィールドの数が多くなったりすると、structのフィールドをマッピングする手間が大きくなったり、マッピングし忘れてゼロ値が引き回されていた!! という事故が起こりやすくなったりします。
go-transform-struct-genは、そういったstructの変換処理を都度手書きする手間をできるだけ減らしたい (減らせるかどうか実験したい) というモチベーションから生まれました。あとは go/ast に入門したかったとか……。
使い方
先述したようなstructが適当なパッケージにあるとして、以下のコマンドで変換関数 (メソッド) を生成できます。
% transform-struct-gen -src-struct '*github.com/utgwkk/go-transform-struct-gen/internal/fixtures/bar.BarModel' -dst-struct '*github.com/utgwkk/go-transform-struct-gen/internal/fixtures/foo.FooModel' -name ToFoo -type method // This file is generated by github.com/utgwkk/go-transform-struct-gen package bar import "github.com/utgwkk/go-transform-struct-gen/internal/fixtures/foo" func (src *BarModel) ToFoo() *foo.FooModel { return &foo.FooModel{ Age: src.Age, Id: src.Id, Name: src.Name, } }
変換元のstructのフィールドにtagを書くことで、どのフィールドにマッピングしたいかを指定することもできます。-
を指定するとマッピング対象から除外することを明示できます。
package bar type BarModel struct { Id string `transform_struct:"dst_field=Id"` Name string `transform_struct:"dst_field=Name"` Age int `transform_struct:"dst_field=Age"` CreatedAt time.Time `transform_struct:"-"` UpdatedAt time.Time `transform_struct:"-"` }
transform_strut
tagを既存のstruct定義に埋め込むツールも用意してあります (READMEで一切言及していないので書き足したい!!)。変換元のstructのフィールドと変換先のstructのフィールドのレーベンシュタイン距離を計算して、最も小さいフィールド同士を変換するようにstruct tagを埋め込むようにしています。あまりフィールド名が違いすぎるとマッピングされないので、そのときは手でstruct tagを埋めてくださいということにしています。
とりあえず手元で使ってみて、なにか進展があったらまた記事を書こうと思います。ヒマができたら……