我々は日々、YAMLを書くことを強いられています。先週も書きました。来週も書くでしょう。RustaceanはTOMLを書いているかもしれないです*1*2。
最近、ぎょうむで、いい感じのコードを書きました。悪いYAMLを検査します。だいたいこんな感じです:
package main import ( "fmt" "os" "gopkg.in/yaml.v3" ) type DuplicateKeyChecker struct{} func (c *DuplicateKeyChecker) UnmarshalYAML(value *yaml.Node) error { switch value.Kind { case yaml.MappingNode: var keys []*yaml.Node for i := 0; i+1 < len(value.Content); i += 2 { key, val := value.Content[i], value.Content[i+1] keystr := key.Value if key.Kind != yaml.ScalarNode { return fmt.Errorf("%s: unsupported key kind (%d)", keystr, key.Kind) } if err := val.Decode(c); err != nil { return fmt.Errorf("%s.%s", keystr, err) } keys = append(keys, key) } keyset := make(map[string]struct{}) for _, key := range keys { keystr := key.Value if _, found := keyset[keystr]; found { return fmt.Errorf("%s: duplicate key (L%dC%d)", keystr, key.Line, key.Column) } keyset[keystr] = struct{}{} } default: for i := range value.Content { if err := value.Content[i].Decode(c); err != nil { return fmt.Errorf("%d.%s", i, err) } } } return nil } func main() { if err := yaml.Unmarshal([]byte(` --- price: 200 price: 300 --- price: price: 100 `), new(DuplicateKeyChecker)); err != nil { fmt.Println(err) os.Exit(1) } }
結構好きな感じのコードです。実体がstruct{}の型を定義する度に、いい気分になれます。
好きなRustの型はstd::marker::PhantomData<T>です👻 *3*4
あんまり良くない点は、unmaintainedなライブラリ https://github.com/go-yaml/yaml に依存していることです。
読まなきゃいけない:
songmu.jp
まあ、!binaryとかに対応してないんですけど。
blog.flatt.tech
ってか対応すべきなんですか?!binary cHJpY2U=とpriceの等価性って、アプリケーションが勝手に決めるのが正しい姿勢なんですかね?
YAMLの仕様はかなりめんどくさそうだなぁとはずっと思っていて、たとえばアンカー/エイリアス/マージとかも気にしてないです。
social.mikutter.hachune.net
読み直さなければいけない:
sg.wantedly.com
当コードは、rust-clippyをがちゃがちゃした経験が生きた気がしました。rust-clippyにPRを送りつけるのは結構いい気分になるのでみなさんおすすめです。Rustの構文木の気分が味わえます(味わわなくてはいけない)し、rust-clippyって結構しょっちゅうルールが増減する気がするんですが、自分で貢献してみると、まあそういうもんやなみたいな気持ちになれます。別にrust-clippyじゃなくてもそうかもしれないです。rustcを壊してみんなのコードのコンパイルを通せなくしちゃったりすると少し申し訳なくなるんじゃないかという気もするんですが*7、みんなのコードに間違えてclippy warningを出しまくってしまったとしても、まあええか、みたいな気持ちでいます。全世界でのGitHub Actionsのログストレージ使用量が少し増えるくらいだと思います。
github.com
当時はなかったのですが(時期的なものなんでしょうか?)、「今なおしてくれるとアツい!」みたいなissue一覧もあるらしいです。夏は暑いですが、feature freeze中にアツいissueを直してみるなど、いかがでしょうか。
github.com
*1:なんかRON https://github.com/ron-rs/ron っていうのもあるらしいです。 ZigにはZONっていうのがあるらしいです。 https://zenn.dev/smallkirby/articles/10dbe02303a201
*2:最近 gitui https://github.com/gitui-org/gitui ってのを試しかけて、RON設定ファイルがでてきました。あんまり好きになれなかったです。最近lazygit https://github.com/jesseduffield/lazygit を使い始めて結構好んでいるのですが、その話はまた今度機会があれば。
*3:ここで出すべきは()型だというかもしれませんが、僕はこの行では僕が好きな型の話をしているのです!
*4:好きな記事です: https://keens.github.io/blog/2017/02/09/rustnochottoyarisuginabuilderpata_n/
*5:僕は今のところセキュリティエンジニアではありません。なのでだいぶ気にしなくていい。
*6:ちなみに、使ったことはあります。便利なのでおすすめです。
*7:だからといって未来永劫するつもりはない、と言うつもりもありませんが