以下の内容はhttps://cookies.hatenablog.jp/entry/2025/07/20/123136より取得しました。


最近のコード: YAMLDuplicateKeyChecker

我々は日々、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

エイリアスとか、使う方が悪い*5*6


当コードは、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:だからといって未来永劫するつもりはない、と言うつもりもありませんが




以上の内容はhttps://cookies.hatenablog.jp/entry/2025/07/20/123136より取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14