import Foundation import NIOCore struct Message: Equatable, Hashable { struct Content: Equatable, Hashable { let time: UInt32 let id: UInt32 init(time: UInt32, id: UInt32) { self.time = time self.id = id } init(decodeFrom data: T) where T.Element == UInt8 { self.time = UInt32(data: data.prefix(4)) self.id = UInt32(data: data.dropFirst(4)) } static var length: Int { MemoryLayout.size * 2 } var encoded: Data { time.encoded + id.encoded } var bytes: [UInt8] { time.bytes + id.bytes } } let mac: Data let content: Content init(mac: Data, content: Content) { self.mac = mac self.content = content } init?(decodeFrom buffer: ByteBuffer) { guard let data = buffer.getBytes(at: 0, length: Message.length) else { return nil } self.init(decodeFrom: data) } var encoded: Data { mac + content.encoded } var bytes: [UInt8] { Array(mac) + content.bytes } } extension UInt32 { init(data: T) where T.Element == UInt8 { self = data .enumerated() .map { UInt32($0.element) << ($0.offset * 8) } .reduce(0, +) } var encoded: Data { .init(bytes) } var bytes: [UInt8] { (0..<4).map { UInt8((self >> ($0*8)) & 0xFF) } } }