こういうのをたまにやります。


public struct Event: Decodable {
    public let id: String
    public let createdAt: NSDate
    public let payload: Payload

    public static func decode(e: Extractor) throws -> Event {
        guard let typeObject = e.rawValue["type"] else {
            throw DecodeError.MissingKeyPath("type")
        }

        guard let typeString = typeObject as? String else {
            throw DecodeError.TypeMismatch(expected: "String", actual: "\(typeObject)", keyPath: "type")
        }

        guard let value = e.rawValue["payload"], payloadObject = value else {
            throw DecodeError.MissingKeyPath("payload")
        }

        let paylaod = try Payload(string: typeString, object: payloadObject)

        return try build(Event.init)(
            e <| "id",
            e <| "created_at",
            paylaod
        )
    }

    ...
}

Himotokiのbuild(_:)(...)は1つ目の括弧の引数にSelf.DecodedTypeを返すstatic funcまたはinitializerを渡し、2つ目の括弧にはその引数を渡すようになっています。2つ目の括弧の各e <| "key"の型は、1つ目の括弧のstatic funcやinitializerから型推論され、Extractor.value<T>(_:) -> T等によって目的の型にデコードされて、引数が完成するという仕組みになっています。

今回のケースではpayloadというプロパティがJSONのフィールドと1対1の関係にないため、e <| "payload"という書き方ができません。なので、真心を込めて手で引数を組み立てて、build(_:)(...)の2つ目の括弧に渡しているというわけです。