diff --git a/Sources/AWSLambdaEvents/DynamoDB.swift b/Sources/AWSLambdaEvents/DynamoDB.swift index 2e6907f..d199e18 100644 --- a/Sources/AWSLambdaEvents/DynamoDB.swift +++ b/Sources/AWSLambdaEvents/DynamoDB.swift @@ -462,11 +462,14 @@ extension DynamoDBEvent { func decode(_ type: String.Type, forKey key: K) throws -> String { let value = try getValue(forKey: key) - guard case .string(let string) = value else { + switch value { + case .string(let string): + return string + case .binary(let binary): + return Data(binary).base64EncodedString() + default: throw self.createTypeMismatchError(type: type, forKey: key, value: value) } - - return string } func decode(_ type: Double.Type, forKey key: K) throws -> Double { @@ -651,11 +654,14 @@ extension DynamoDBEvent { } func decode(_: String.Type) throws -> String { - guard case .string(let string) = self.value else { + switch self.value { + case .string(let string): + return string + case .binary(let binary): + return Data(binary).base64EncodedString() + default: throw self.createTypeMismatchError(type: String.self, value: self.value) } - - return string } func decode(_: Double.Type) throws -> Double { @@ -769,6 +775,9 @@ extension DynamoDBEvent { self.codingPath = codingPath self.array = array self.count = array.count + + // No need to decode if array is empty + self.isAtEnd = array.isEmpty } mutating func decodeNil() throws -> Bool { diff --git a/Tests/AWSLambdaEventsTests/DynamoDBTests.swift b/Tests/AWSLambdaEventsTests/DynamoDBTests.swift index e3b1948..4e53f17 100644 --- a/Tests/AWSLambdaEventsTests/DynamoDBTests.swift +++ b/Tests/AWSLambdaEventsTests/DynamoDBTests.swift @@ -251,4 +251,59 @@ struct DynamoDBTests { #expect(test?.foo == "bar") #expect(test?.xyz == 123) } + + @Test func decoderEmptyList() { + let value: [String: DynamoDBEvent.AttributeValue] = [ + "fooList": .list([]) + ] + + struct Test: Codable { + let fooList: [Int] + } + + let test = try? DynamoDBEvent.Decoder().decode(Test.self, from: value) + #expect(test?.fooList == []) + } + + @Test func decoderNonEmptyList() { + let value: [String: DynamoDBEvent.AttributeValue] = [ + "fooList": .list([.string("test")]) + ] + + struct Test: Codable { + let fooList: [String] + } + + let test = try? DynamoDBEvent.Decoder().decode(Test.self, from: value) + #expect(test?.fooList == ["test"]) + } + + @Test func decoderBinaryToBase64KeyedDecodingContainer() { + let value: [String: DynamoDBEvent.AttributeValue] = [ + "xyz": .binary([0x74, 0x65, 0x73, 0x74]) // UTF8 for "test" + ] + + struct Test: Codable { + let xyz: String + } + + let test = try? DynamoDBEvent.Decoder().decode(Test.self, from: value) + #expect(test?.xyz == "dGVzdA==") // base64 for "test" + } + + @Test func decoderBinaryToBase64SingleValueDecodingContainer() { + let value: DynamoDBEvent.AttributeValue = .binary([0x74, 0x65, 0x73, 0x74]) // UTF8 for "test" + + let test = try? DynamoDBEvent.Decoder().decode(String.self, from: value) + #expect(test == "dGVzdA==") // base64 for "test" + } + + @Test func decoderBinaryToBase64UnkeyedDecodingContainer() { + let value: DynamoDBEvent.AttributeValue = .list([ + .binary([0x74, 0x65, 0x73, 0x74]) // UTF8 for "test" + ]) + + let test = try? DynamoDBEvent.Decoder().decode([String].self, from: value) + #expect(test == ["dGVzdA=="]) // base64 for "test" + } }