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