SIONというシリアライゼーションフォーマットを提案します。Swiftによるレファランス実装はこちら。
SIONという名前は Swift Interchangeable Object Notation からとりました。名前の通りSwiftのリテラルが元になっています。以下はSIONで表現されたデータの一例です。
[
    "array" : [
        nil,
        true,
        1,
        1.0,
        "one",
        [1],
        ["one" : 1.0]
    ],
    "bool" : true,
    "data" : .Data("R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7"),
    "date" : .Date(0x0p+0),
    "dictionary" : [
        "array" : [],
        "bool" : false,
        "double" : 0x0p+0,
        "int" : 0,
        "nil" : nil,
        "object" : [:],
        "string" : ""
    ],
    "double" : 0x1.518f5c28f5c29p+5,
    "int" : -42,
    "nil" : nil,
    "string" : "漢字、カタカナ、ひらがなの入ったstring😇",
    "url" : "https://github.com/dankogai/"
]
見ての通り、
- (
Dictionary|Object|Map)は{}ではなく[]で囲っている - 
Dataは.Data("base64encoded")と表現。ここでbase64encodedはBase64でエンコードされたバイト列。 - 
Dateは.Date(timeIntervalSince1970)と表現。ここでtimeIntervalSince1970は1970年01月01日00:00:00GMTからの経過時間をDoubleで表現したもの(SwiftのDate型の内部表現)。 
としています。
動機
要はJSONは痒くても掻けなかったところを掻けるようにしたかったということです。痒いところというのは以下のとおり。
- 数値が
Number、実質上のDoubleしかなく、数値データがlossyになりがち- 
IntとDoubleをきちんと分けたい 
 - 
 - 
String以外のキーが使えない - 
DataとDateをサポートしていない 
MessagePackはこれらをすベて解決していますが、しかしMessagePackはバイナリー。データ交換には最適でもデータ視覚化には何らかの形でそれをテキスト化する必要がある。しかしJSONでは漏れが出る。というわけでたどり着いたのが Swift のリテラルだったわけです。
参考に各種データシリアライゼーションフォーマットの各種データのサポート状況を表にまとめました。
| Type | SION | MsgPack | JSON | Property List | Comment | 
|---|---|---|---|---|---|
Nil | 
✔︎ | ✔︎ | ✔︎ | ❌ | plist: .binary only | 
Bool | 
✔︎ | ✔︎ | ✔︎ | ✔︎ | |
Int | 
✔︎ | ✔︎ | ❌ | ✔︎ | 64bit | 
Double | 
✔︎ | ✔︎ | ✔︎ | ✔︎ | JSON's Number | 
String | 
✔︎ | ✔︎ | ✔︎ | ✔︎ | utf-8 encoded | 
Data | 
✔︎ | ✔︎ | ❌ | ✔︎ | binary blob | 
Date | 
✔︎ | ✔︎ | ❌ | ✔︎ | .timeIntervalSince1970 in Double
 | 
[Self] | 
✔︎ | ✔︎ | ✔︎ | ✔︎ | aka Array | 
[String:Self] | 
✔︎ | ✔︎ | ✔︎ | ✔︎ | aka Object, Map… | 
[Self:Self] | 
✔︎ | ✔︎ | ❌ | ❌ | non-String keys | 
レファランス実装
その最初のレファランス実装であるswift-sionは、本記事執筆現在
- 
SION型の生成と操作。操作感はswift-jsonと同様 - JSONとの相互変換
 - Property Listとの相互変換
 - YAMLへの出力(出力のみ)
 
をサポートしています。
TODO
- 他言語での実装
 - MessagePackとの相互変換
 
さいごに
ご意見をお待ちしております。
Dan the Safe, Fast and Expressive