Closed mo5tone closed 5 months ago
@mo5tone while there might be bug regarding optional types support in CodedAs
macro, the code snippet you have provided for decoding the sample JSON mentioned seems to be wrong. Especially the @CodedAt("data", "attributes", "operation")
attached to protocol ResponseAttributes
, in your Response
you have already provided path to the ResponseAttributes
container as data.attributes
, specifying the path data.attributes
again for the protocol type identifier makes the path of the identifier key data.attributes.data.attributes.operation
which is wrong according to your JSON.
@soumyamahunt thanks for your correction.
Now the generated ResponseAttributesCoder
works like a charm. Will close this issue.
Thanks again for your great library.
Describe the bug I want to handle below two JSONs with
DynamicCodable
.JSON to handle
```json { "data": { "id": "some UUID", "type": "Foo.Bar", "attributes": { "id": "another UUID", "expiresIn": 3600, "xxx-token": "xxxxxx", "yyy-token": "yyyyyyyyy" } } } ``` and ```json { "data": { "id": "some UUID", "type": "Foo.Bar", "attributes": { "id": "another UUID", "mac": "message authentication code", "challenge": "some challenge", "operation": "REGISTRATION", "status-code": "200" } } } ```However the code which followed
Tests/MetaCodableTests/DynamicCodable/PostPage.swift
generate incorrectHelperCoder
My code
```swift @Codable @CodedAsGenerated `HelperCoder`
```swift import MetaCodable struct ResponseAttributesCoder: HelperCoder { func decode(from decoder: any Decoder) throws -> ResponseAttributes { let container = try decoder.container(keyedBy: CodingKeys.self) if (try? container.decodeNil(forKey: CodingKeys.data)) == false { let data_container = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.data) if (try? data_container.decodeNil(forKey: CodingKeys.attributes)) == false { let attributes_data_container = try data_container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.attributes) let type = try attributes_data_container.decodeIfPresent(String.self, forKey: CodingKeys.type) // ❌ } else { let type = nil // ❌ } } else { let type = nil // ❌ } switch type { // ❌ case RegistrationAttributes.identifier: let _0 = try RegistrationAttributes(from: decoder) return _0 case VerificationAttributes.identifier: let _0 = try VerificationAttributes(from: decoder) return _0 default: let context = DecodingError.Context( codingPath: decoder.codingPath, debugDescription: "Couldn't match any cases." ) throw DecodingError.typeMismatch(ResponseAttributesCoder.self, context) } } func encode(_ value: ResponseAttributes, to encoder: any Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) var data_container = container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.data) var attributes_data_container = data_container.nestedContainer(keyedBy: CodingKeys.self, forKey: CodingKeys.attributes) var typeContainer = attributes_data_container switch value { case let _0 as RegistrationAttributes: try typeContainer.encodeIfPresent(RegistrationAttributes.identifier, forKey: CodingKeys.type) try _0.encode(to: encoder) case let _0 as VerificationAttributes: try typeContainer.encodeIfPresent(VerificationAttributes.identifier, forKey: CodingKeys.type) try _0.encode(to: encoder) default: break } } enum CodingKeys: String, CodingKey { case type = "operation" case data = "data" case attributes = "attributes" } } ```To Reproduce Steps to reproduce the behavior:
MetaCodable
to dependenciesExpected behavior A clear and concise description of what you expected to happen.
MetaProtocolCodable
plugin should handle optional type correctly.Environment (please complete the following information, remove ones not applicable):