🌊

Go のデバッグやコード生成に便利な pretty print できるライブラリ「dd」を作った

2022/03/24に公開約3,100字

github.com/Code-Hex/dd という Go の構文として有効なフォーマットで pretty print を行えるライブラリを作成しました。(Star をくれると大喜びします)

色付き pretty print をするとこんな感じになります。

作った背景

pretty print 可能なライブラリは既にいくつか存在します。有名どころだと github.com/davecgh/go-spew/spewgithub.com/k0kubun/pp/v3 があります。私はこれらのライブラリがとても好きで良く利用しています。パッケージ名は k0kubun/pp を真似しています。こちらは data dumper の略で dd です。

しかし、JSON や YAML などのデータを Go の構造体へマッピングし、その結果をテストデータとして比較したい時に、上記で紹介したライブラリの出力結果をもとに加工して利用するといったことをしたいケースがありました。しかし、人が読みやすい形で出力されていることから、その加工を行うのがまあまあ大変でした。そこで Go の構文としてそのまま利用できる形で出力ができればもっと楽ができるなと思い作り始めました。

使い方

コード生成目的

次の行を記述することで dd.Dump(data interface{}, opts ...dd.OptionFunc) string という関数が利用できるようになります。

import "github.com/Code-Hex/dd"

data の部分にはどんなデータ構造でもシュッと渡すことができます。そうすると Go の構文として利用可能なフォーマットの文字列が手に入ります。

data := map[string]int{
  "b": 2,
  "a": 1,
  "c": 3,
}
fmt.Println(dd.Dump(data))
// map[string]int{
//   "a": 1,
//   "b": 2,
//   "c": 3,
// }

// いくつかオプションもあります
fmt.Println(dd.Dump(data, dd.WithIndent(4)))
// map[string]int{
//     "a": 1,
//     "b": 2,
//     "c": 3,
// }

デバッグ目的

次の行を記述することで p.P(args ...interface{}) (int, error) という pretty print を行える関数を利用することができます。

import "github.com/Code-Hex/dd/p"

fmt パッケージの Println と同じように複数のデータを一度に渡すこともできます。

srv := &http.Server{
  Addr:    ":8080",
  Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}),
}
p.P("server data", srv) // default theme は monokai

次のコードを利用すると始めの方で紹介した画像のような結果が手に入ります。また、ベースとなっている dd パッケージのオプションを適用したり、自分の好きなカラーテーマで出力をしたりするオプションも提供しています。

srv := &http.Server{
  Addr:    ":8080",
  Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}),
}
fmt.Println("--- monokai")
p1 := p.New(p.WithDumpOptions(dd.WithExportedOnly()))
p1.P(srv)

fmt.Println("--- doom-one")
p2 := p.New(
  p.WithStyle(styles.DoomOne),
  p.WithDumpOptions(dd.WithExportedOnly()),
)
p2.P(srv)

型によって出力内容を変更する

dd パッケージには WithDumpFunc というオプションも用意してます。このオプションは面白いことに Go 1.18 以上だとジェネリクスを利用し、それ以外だと reflect を使うような挙動になっています。

このオプションをラップし、[]bytejson.RawMessage などをいい感じに出力してくれるオプションも df パッケージで提供しています。

import "github.com/Code-Hex/dd/df"

提供されているオプションと dd.Dump 関数をこんな感じで組み合わせて利用可能です。

// json.RawMessage(`{"message":"Hello, World"}`)
fmt.Println(
  dd.Dump(
    json.RawMessage(`{"message":"Hello, World"}`),
    df.WithJSONRawMessage(),
  ),
)

// func() []byte {
//   // 00000000  48 65 6c 6c 6f 2c 20 57  6f 72 6c 64              |Hello, World|
//
//   return []byte{0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x2c, 0x20, 0x57, 0x6f, 0x72, 0x6c, 0x64}
// }()
fmt.Println(
  dd.Dump([]byte("Hello, World"), df.WithRichBytes()),
)

最後に

Playground のリンクも貼っておきます。是非お試しください!そして Star もください😇

https://go.dev/play/p/FX1fcrCsdUw

GitHub issuestwitter にでもフィードバックをお待ちしております。

Discussion

ログインするとコメントできます