作ったもの
JSONを見やすく整形し、要素の型に応じて色を付けて表示するCLIを作成した。
小さなJSONを確認したい場合に、ただ整形して出力するだけでは、どの値が何の意味を持つのかなどが分かりづらい。また、見やすくするためにエディタを開くのもめんどくさい。
そのため、色付けしてすぐに出力するツール作ってしまえと思い、今回のCLIを作成してみた。
作成物は https://github.com/x-color/jc に上げてある。
使用したライブラリ
spf13/cobra はCLI作成用のライブラリ。これを使用すると簡単にいい感じのCLIを作成することができるのでとても便利。
内部での処理 (未知のJSONを解析する方法)
Go言語であらかじめ構造がわかっているJSONを読み込む際には、構造体を事前に定義することで構造体に値を流し込むことができる。
しかし、未知のJSONを読み込む際には、構造体を事前に定義することができない。構造体を定義しないでGoの標準の機能を用いてJSONを読み込むと、読み込んだデータの型は interface{}
となってしまい型固有の様々な処理を行うことができなくなってしまう。
なので、読み込んだデータに対して何か処理を行いたい場合は、処理内容に応じて型を変換する必要が出てくる。
今回作成したCLIでは、
- 色を付ける要素(数値、文字列、真偽値)の判定
- オブジェクトと配列の中の要素を取得
の2点を行うために、型変換を行う必要があった。
interface{}
を別の型に変換する際には、switchとType Assertionを用いると簡単にできる。
実際に使用したコードを簡略化したものが以下のものとなる。
func dataToString(data interface{}) string {
switch convertedData := data.(type) {
case int64, float64:
return numberToString(data) // 要素が数値の時の処理
case bool:
return boolToString(data) // 要素が真偽値の時の処理
case string:
return stringToString(data) // 要素が文字列の時の処理
case []interface{}
return sliceToString(convertedData) // 要素が配列の時の処理
case map[string]interface{}:
return objToString(convertedData) // 要素がオブジェクトの時の処理
}
return ""
}
上記の関数は、interface{}
型のデータを受け取り、そのデータの型を解析し色付けした文字列に変換していく。
型が[]interface{}
,map[string]interface{}
のときは、sliceToString()
,objToString()
の内部でスライスやマップの持つ要素ごとに再度この関数を呼び出している。
そのため、読み込んだ未知のJSONデータをこの関数に渡すことで、再帰的に型を解析し色付けした文字列に変換していくことができるようになっている。