Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion Sources/Extensions/SingleValueDecodingContainer+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@

import Foundation

enum MessagePackableDecodingError: Error {
case notMessagePackDecoder
}

extension SingleValueDecodingContainer {
func decode<T: MessagePackable>(as type: T.Type) throws -> T where T.T == T {
return try (self as! MessagePackDecoder.SingleValueContainer).decode(as: type)
guard let messagePackContainer = self as? MessagePackDecoder.SingleValueContainer else {
throw MessagePackableDecodingError.notMessagePackDecoder
}
return try messagePackContainer.decode(as: type)
}
}
9 changes: 8 additions & 1 deletion Sources/Extensions/SingleValueEncodingContainer+.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,15 @@

import Foundation

enum MessagePackableEncodingError: Error {
case notMessagePackEncoder
}

extension SingleValueEncodingContainer {
func encode<T: MessagePackable>(_ value: T) throws {
try (self as! MessagePackEncoder.SingleValueContainer).encode(from: value)
guard let messagePackContainer = self as? MessagePackEncoder.SingleValueContainer else {
throw MessagePackableEncodingError.notMessagePackEncoder
}
try messagePackContainer.encode(from: value)
}
}
25 changes: 23 additions & 2 deletions Sources/MessagePackTimestamp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,33 @@ extension MessagePackTimestamp {
}

extension MessagePackTimestamp: Codable {
enum CodingKeys: String, CodingKey {
case seconds
case nanoseconds
}

public func encode(to encoder: Encoder) throws {
try encoder.singleValueContainer().encode(self)
do {
// First, try encoding as a `MessagePackable`, which requires a `MessagePackEncoder`.
try encoder.singleValueContainer().encode(self)
} catch let error as MessagePackableEncodingError where error == .notMessagePackEncoder {
// If the caller is not using a `MessagePackEncoder`, then fall back to standard, non-MessagePack behavior.
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(seconds, forKey: .seconds)
try container.encode(nanoseconds, forKey: .nanoseconds)
}
}

public init(from decoder: Decoder) throws {
self = try decoder.singleValueContainer().decode(as: MessagePackTimestamp.self)
do {
// First, try decoding as a `MessagePackable`, which requires a `MessagePackDecoder`.
self = try decoder.singleValueContainer().decode(as: MessagePackTimestamp.self)
} catch let error as MessagePackableDecodingError where error == .notMessagePackDecoder {
// If the caller is not using a `MessagePackDecoder`, then fall back to standard, non-MessagePack behavior.
let container = try decoder.container(keyedBy: CodingKeys.self)
self.seconds = try container.decode(Int64.self, forKey: .seconds)
self.nanoseconds = try container.decode(Int64.self, forKey: .nanoseconds)
}
}
}

Expand Down
15 changes: 15 additions & 0 deletions Tests/MessagePackerTests/TimestampPackedTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,4 +37,19 @@ class TimestampPackedTests: XCTestCase {
let output = Data([199, 12, 255, 25, 69, 229, 222, 0, 0, 0, 14, 211, 132, 20, 74])
XCTAssertEqual(try encoder.encode(input), output)
}

func testSupportsNonMessagePackEncoder() {
let input = MessagePackTimestamp(seconds: 1542592042, nanoseconds: 209741115)

let jsonEncoder = JSONEncoder()
jsonEncoder.outputFormatting = [.prettyPrinted, .sortedKeys]

let output = """
{
"nanoseconds" : 209741115,
"seconds" : 1542592042
}
""".data(using: .utf8)!
XCTAssertEqual(try jsonEncoder.encode(input), output)
}
}
14 changes: 14 additions & 0 deletions Tests/MessagePackerTests/TimestampUnpackedTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -69,4 +69,18 @@ class TimestampUnpackedTests: XCTestCase {

XCTAssertEqual(try decoder.decode(Vehicle.self, from: input), output)
}

func testSupportsNonMessagePackDecoder() {
let input = """
{
"nanoseconds" : 209741115,
"seconds" : 1542592042
}
""".data(using: .utf8)!

let jsonDecoder = JSONDecoder()

let output = MessagePackTimestamp(seconds: 1542592042, nanoseconds: 209741115)
XCTAssertEqual(try jsonDecoder.decode(MessagePackTimestamp.self, from: input), output)
}
}