通用 (Tōngyòng)

Build Status Swift Package Manager compatible Platform

通用 (Tōngyòng): 一个微小的、零依赖的跨平台 Swift 解析器和解码器,用于 JSON、XML、YAML 和属性列表。

用法 (Yòngfǎ)

将以下依赖项添加到你的 Package.swift 文件中

.package(url: "https://github.com/marcprux/universal.git", from: "5.0.5")

该包提供模块 EitherJSONXMLYAMLPLISTUniversal,后者是一个伞形模块,重新导出所有其他模块。

示例 (Shìlì)

import Universal

func testUniversalExample() throws {
    // JSON Parsing
    let json: JSON = try JSON.parse(Data("""
        {"parent": {"child": 1}}
        """.utf8))

    assert(json["parent"]?["child"] == 1)
    assert(json["parent"]?["child"] == JSON.number(1.0)) // JSON's only number is Double


    // YAML Parsing
    let yaml: YAML = try YAML.parse(Data("""
        parent:
          child: 1
        """.utf8))

    assert(yaml["parent"]?["child"] == 1)
    assert(yaml["parent"]?["child"] == YAML.integer(1)) // YAML can parse integers
    assert(yaml["parent"]?["child"] != 1.0) // not the same as a double

    let yamlJSON: JSON = try yaml.json() // convert YAML to JSON struct
    assert(yamlJSON == json)


    // XML Parsing
    let xml: XML = try XML.parse(Data("""
        <parent><child>1</child></parent>
        """.utf8))

    let xmlJSON: JSON = try xml.json() // convert XML to JSON struct

    assert(xml["parent"]?["child"] == XML.string("1")) // XML parses everything as strings

    // fixup the XML by changing the JSON to match
    assert(json["parent"]?["child"] == 1)
    var jsonEdit = json
    jsonEdit["parent"]?["child"] = JSON.string("1") // update the JSON to match
    assert(jsonEdit["parent"]?["child"] == "1") // now the JSON matches

    assert(xmlJSON == jsonEdit)
}

编码 (Biānmǎ)

通用 (Tōngyòng) 提供了解码 YAML 和 XML 的能力(但不能编码到 YAML 和 XML),通过它们转换为 JSON 结构体的能力实现。

import Universal

struct Coded : Decodable, Equatable {
    let person: Person

    struct Person : Decodable, Equatable {
        let firstName: String
        let lastName: String
        let astrologicalSign: String
    }
}

let decodedFromJSON = try Coded(json: JSON.parse(Data("""
    {
      "person": {
        "firstName": "Marc",
        "lastName": "Prud'hommeaux",
        "astrologicalSign": "Sagittarius"
      }
    }
    """.utf8)))

let decodedFromYAML = try Coded(json: YAML.parse(Data("""
    # A YAML version of a Person
    person:
      firstName: Marc
      lastName: Prud'hommeaux
      astrologicalSign: Sagittarius # what's your sign?
    """.utf8)).json())
assert(decodedFromJSON == decodedFromYAML)

let decodedFromXML = try Coded(json: XML.parse(Data("""
    <!-- An XML version of a Person -->
    <person>
      <firstName>Marc</firstName>
      <!-- escaping and stuff -->
      <lastName>Prud&apos;hommeaux</lastName>
      <astrologicalSign>Sagittarius</astrologicalSign>
    </person>
    """.utf8)).json())
assert(decodedFromYAML == decodedFromXML)

let decodedFromPLISTXML = try Coded(json: PLIST.parse(Data("""
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>person</key>
        <dict>
            <key>firstName</key>
            <string>Marc</string>
            <key>lastName</key>
            <string>Prud&apos;hommeaux</string>
            <key>astrologicalSign</key>
            <string>Sagittarius</string>
        </dict>
    </dict>
    </plist>
    """.utf8)).json())
assert(decodedFromXML == decodedFromPLISTXML)

let decodedFromPLISTOpenStep = try Coded(json: PLIST.parse(Data("""
    {
        person = {
            firstName = Marc;
            lastName = "Prud'hommeaux";
            astrologicalSign = Sagittarius;
        };
    }
    """.utf8)).json())
assert(decodedFromPLISTOpenStep == decodedFromPLISTXML)