Closed3

SwiftでMessagePackライブラリを作る

nabeyangnabeyang

Codableなら動くやつ。arrayかmapか指定できるようにする。デコードはこんなの

    func testFixMap() throws {
        let decoder = MsgPackDecoder()
        struct Pair: Decodable {
            var X: UInt8
            var Y: UInt8
        }
        do {
            let input = Data([0x82, 0xa1, 0x58, 0x12, 0xa1, 0x59, 0x34])
            let out = try decoder.decode(Pair.self, from: input)
            XCTAssertEqual(out.X, 0x12)
            XCTAssertEqual(out.Y, 0x34)
        }
    }

    func testFixMapArray() throws {
        let decoder = MsgPackDecoder()
        struct Pair: Decodable {
            var X: UInt8
            var Y: UInt8
            enum CodingKeys: Int, CodingKey {
                case X
                case Y
            }
        }
        do {
            let input = Data([0x92, 0x12, 0x34])
            let out = try decoder.decode(Pair.self, from: input)
            XCTAssertEqual(out.X, 0x12)
            XCTAssertEqual(out.Y, 0x34)
        }
    }

エンコードはこんなの

    func testFixArray() throws {
        let encoder = MsgPackEncoder()
        do {
            let input: [UInt8] = [0x12, 0x34, 0x56]
            XCTAssertEqual(try encoder.encode(input).hexDescription, "93123456")
        }
    }

    func testFixMap() throws {
        let encoder = MsgPackEncoder()
        do {
            struct Pair: Encodable {
                var X: UInt8
                var Y: UInt8
            }
            let input: Pair = .init(X: 0x12, Y: 0x34)
            XCTAssertEqual(try encoder.encode(input).hexDescription, "82a15812a15934")
        }
    }

ArrayにしたいときはCodingKeysを書かないといけないのは、仕方ないか。

nabeyangnabeyang

AnyCodable型を作って、雑に使えるようになった(0.2.1)。

import SwiftMsgpack

struct Coordinate: Codable {
    var latitude: Double
    var longitude: Double
}

struct Landmark: Codable {
    var name: String
    var foundingYear: Int
    var location: Coordinate
}

let input = Landmark(
    name: "Mojave Desert",
    foundingYear: 0,
    location: Coordinate(
        latitude: 35.0110079,
        longitude: -115.4821313
    )
)
let encoder = MsgPackEncoder()
let decoder = MsgPackDecoder()
let data = try! encoder.encode(input)
let out = try! decoder.decode(Landmark.self, from: data)
let any = try! decoder.decode(AnyCodable.self, from: data)

print([UInt8](data))
// [131, 164, 110, 97, 109, 101, 173, 77, 111, 106,
//  97, 118, 101, 32, 68, 101, 115, 101, 114, 116,
//  172, 102, 111, 117, 110, 100, 105, 110, 103, 89,
//  101, 97, 114, 0, 168, 108, 111, 99, 97, 116,
//  105, 111, 110, 130, 168, 108, 97, 116, 105, 116,
//  117, 100, 101, 203, 64, 65, 129, 104, 180, 245,
//  63, 179, 169, 108, 111, 110, 103, 105, 116, 117,
//  100, 101, 203, 192, 92, 222, 219, 61, 61, 120,
//  49]

print(out)
// Landmark(
//   name: "Mojave Desert",
//   foundingYear: 0,
//   location: example.Coordinate(
//     latitude: 35.0110079,
//     longitude: -115.4821313
//   )
// )

print(any)
// AnyCodable(
//     [
//         AnyCodable("foundingYear"): AnyCodable(0),
//         AnyCodable("name"): AnyCodable("Mojave Desert"),
//         AnyCodable("location"): AnyCodable(
//             [
//                 AnyCodable("longitude"): AnyCodable(-115.4821313),
//                 AnyCodable("latitude"): AnyCodable(35.0110079),
//             ]
//         ),
//     ]
// )
このスクラップは2022/10/01にクローズされました