LoginSignup
9
9

More than 5 years have passed since last update.

JSONSchemaからstructのようなコードを生成する"structr"というのを書いた

Last updated at Posted at 2016-04-14

TL;DR

  • https://github.com/dameleon/structr
  • JSONSchema draft v4のspecに沿ったJSONSchemaを入力すると、設定ファイルに記したtemplateを使ってJSONSchemaの構造を出力する
  • 書いた、とは言ったもののまだテストもドキュメントも書き途中

motivation

最近、どんどん型になっていってる中で通信部分で受けたデータをstructにマップするような実装を毎回手書きで書くのはしんどくなってきておりガッとgolangで実装してみた。
golangにしたのは、いずれはWindows環境やweb上(gopher.js)でも動けばいいなーとか。(まだ何も試してない)

templateはわりと柔軟に記述できるので、JSONSchemaを書く手間はあるもののわりとどんな言語でも出力できる。ただ、文字コードとか改行コードに関しては現在ノータッチ。

使い方

大体はREADME.mdに書いたとおりだが、

yamlで設定ファイルを記述する

# JSONSchemaの型を変換するための定義を `"JSONSchemaの型": "変換する型"` のように指定
# 渡されるデータの構造は `struct{ .Type string, .InnerType string }`
type_translate_map:
  string: "String"
  integer: "Int"
  number: "Float"
  boolean: "Bool"
  null: "nil"
  array: "[{{.InnerType}}]"
  object: "{{.InnerType}}"

# ファイルとして出力する場合のファイル名にするテンプレートを指定
# 渡されるデータは `StructureNode`
output_filename: "{{.Name}}.swift"

# 入力するJSONSchemaに"$ref"(draft v4にある他のSchemaを参照する指定)があった場合、その参照先のSchemaを出力するか
output_dependencies: true

# 出力するstruct(のようなファイル)のテンプレートをgolangの`text/template`で使える記法で記述
# 渡されるデータは `StructureNode`
structure_template: |
  struct {{.Name|toUpperCamelCase}} {
  {{range .Properties}}
      var {{.Name}}: {{.Type|translateTypeName|toUpperCamelCase}}?{{end}}

  {{.Children|extractStructures}}
  }

# `StructureNode`の`.Children`を展開したときに、ネストする為の文字列を指定
child_structures_nesting: "    "

上記の設定ファイルは、以下のコマンドによってテンプレートが得られる

$ structr template 

コマンドを実行

# Stdoutに出力
$ structr generate -c ${設定ファイル} ${入力するファイルパス}

# 特定のディレクトリに出力
$ structr generate -c ${設定ファイル} --ourDir ${出力先のパス} ${入力するファイルパス}

のように指定する。
入力するファイルパスは内部でGlobしているので、your/schema/*.jsonのように指定できる(はず)

大体以下のような感じでstructっぽいものを出力してくれる。

struct YourStruct {

    var hoo: String?   
    var bar: String?  
    var child: ChildStruct?
    var dependency: YourDependencyStruct?

    struct ChildStruct {

        var baz: String?

    }

}

struct YourDependencyStruct {

    var hoge: String?
    var fuga: String?
    var piyo: String?

}

今後の予定

  • テストを書く
  • 詳細なドキュメントを書く
  • Windowsでも動くように
  • 文字コード, 改行コードの処理
  • http(s)経由でJSONSchemaを取得して出力する
  • 処理速度に対してまったく気を遣ってないのでその辺の対応
  • "$ref"で指定されたJSONSchemaの取り回すらへんをもうちょっと綺麗にしたい
  • 普通のjsonからでも出力できるようにする

などを予定してます。


初めてgolangをガッツリ書いたので結構時間がかかった。
変な記述とかそれなりにあると思うので、レビュー, 要望などお待ちしております。

9
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
9