SwiftでEnumで快適にJson扱うライブラリEJson

Functional Programming in Swift
http://www.objc.io/books/

を読みながら、どうしてもEnumでJsonを表現するライブラリを作ってみたかったのです。
型セーフ、スレッドセーフで、案外いい感じです。
実際違ったアプローチで遊んでみたいという思いがこれを作らせました。
新しいビジョンが得られれば幸いです。

**そこ、SwiftyJSONでいいとか言わない！ まったくもう！**

リポジトリはこちら
https://github.com/Ushio/EnumJson

※ また、Swift 1.2 なのでご注意ください。
※ Carthageに対応しています。

### 定義

```swift
public enum Json {
    case JObject  ([String : Json])
    case JArray   ([Json])
    case JNumber  (NSNumber)
    case JString  (String)
    case JBoolean (Bool)
    case JNull
}
```

とてもシンプルです。Dictionary,Arrayが一段挟まっているので再帰的定義に小細工は必要ありません。
要するにこれがやりたかっただけです。

### 生成

```swift
let json: Json = [
    "string" : "string_value",
    "number_double" : 10.5,
    "number_int" : 15,
    "boolean" : true,
    "null" : nil,
    "array" : ["red", "green", "blue"],
    "object" : [
        "one" : 1,
        "two" : 2,
        "three" : 3
    ]
]
```

もろもろConvertibleが用意されているので、直感的に記述できます。

### 書き出しや読み込み

```swift

if let data = json.jsonData {
  // do something
}
```

```swift
if let json = EJson(data: data) {
  // do something
}
```

### アクセスショートカット
```swift
let json: Json = [
    "string" : "string_value",
    "number_double" : 10.5,
    "number_int" : 15,
    "boolean" : true,
    "null" : nil,
    "array" : ["red", "green", "blue"],
    "object" : [
        "one" : 1,
        "two" : 2,
        "three" : 3
    ]
]
let string_value: String? = json["string_value"]?.string
let green: String? = json["array" ~> 1]?.string
let three: Double? = json["object" ~> "three"]?.double
```

### 値のセット
subscriptで値をセットします。

```swift
var json: Json = [:]

json["string_key"] = "string"
json["key1" ~> "key2"] = true
json["key3"] = "a"
json["key3"] = "c"

let yes = json == [
    "string_key" : "string",
    "key1" : ["key2" : true],
    "key3" : "c"
]
```

### 削除
nilをsubscriptで代入することで削除できます。

```swift
var json: Json = [
    "string" : "string_value",
    "number_double" : 10.5,
    "number_int" : 15,
    "array" : ["red", "green", "blue", "blue"],
    "object" : [
        "one" : 1,
        "two" : 2,
        "three" : 3
    ]
]

json["number_int"] = nil
json["array" ~> 1] = nil
json["object" ~> "one"] = nil

let yes = json == [
    "string" : "string_value",
    "number_double" : 10.5,
    "array" : ["red", "blue", "blue"],
    "object" : [
        "two" : 2,
        "three" : 3
    ]
]
```

###オブジェクトへのマッピング

Swift 1.2ではifでシンプルに記述できるようになりました。

```
struct User {
    let number: Double
    let name: String

    static func fromJson(json: Json) -> User? {
        if
            let number = json["number"]?.double,
            let name = json["name"]?.string
        {
            return User(number: number, name: name)
        }
        return nil
    }
}

let json: Json = [
    "number" : 17.4,
    "name" : "ken"
]

if let user = User.fromJson(json) {
    // do something
}

```

※<*>演算子はEnumJsonから外すことにしました。ただ面白い手法なので、興味のある方はこちらの記事をお勧めします。
http://qiita.com/koher/items/95583f58a443f6a33c28

###まとめ
単なる一発ネタだったのですが、組み立ててみると案外使えるものができたような気がしないでもないです（弱）

#### TODO リスト

* 名前空間（対応済み）
* asXxx => xxx　（対応済み）
* Carthage対応　（対応済み）
* 数値精度問題対応　（不完全ではあるが、一部対応済み）

Carthage対応し、バージョン1.0を正式に決めました。
初期バージョンからは要素の削除や追加の方法がよりシンプルになるなど微調整が含まれています。