Skip to content

Arrays of enums #91

@flowbe

Description

@flowbe

I am trying to decode this XML:

<?xml version="1.0" encoding="UTF-8"?>
<container>
    <p>
        <run>
            <id>1518</id>
            <text>I am answering it again.</text>
        </run>
        <properties>
            <id>431</id>
            <title>A Word About Wake Times&#xD;</title>
        </properties>
        <br />
    </p>
    <p>
        <run>
            <id>1519</id>
            <text>I am answering it again.</text>
        </run>
    </p>
</container>

This is my implementation:

struct Run: Decodable {
    let id: Int
    let text: String
}

struct Properties: Decodable {
    let id: Int
    let title: String
}

struct Break: Decodable {
    
}

enum Entry: Decodable {
    case run(Run)
    case properties(Properties)
    case br(Break)
    
    private enum CodingKeys: String, CodingKey {
        case run, properties, br
    }
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.container(keyedBy: CodingKeys.self)
        do {
            self = .run(try container.decode(Run.self, forKey: .run))
        } catch DecodingError.keyNotFound {
            do {
                self = .properties(try container.decode(Properties.self, forKey: .properties))
            } catch DecodingError.keyNotFound {
                self = .br(try container.decode(Break.self, forKey: .br))
            }
        }
    }
}

struct Paragraph: Decodable {
    let entries: [Entry]
    
    public init(from decoder: Decoder) throws {
        let container = try decoder.singleValueContainer()
        entries = try container.decode([Entry].self)
    }
}

do {
    let result = try XMLDecoder().decode([Paragraph].self, from: data)
    for paragraph in result {
        print("Paragraph :")
        for entry in paragraph.entries {
            switch entry {
            case .run(let run):
                print("Run : \(run)")
            case .properties(let properties):
                print("Properties : \(properties)")
            case .br(let br):
                print("Break : \(br)")
            }
        }
        print("End paragraph")
    }
}
catch {
    print(error)
}

But I am getting an odd DecodingError.keyNotFound

I know that there is already an issue about enums but I think this one is different because I am trying to do an array of array of enums and I don't get the same error.

I am using an enum because I want to be able to decode a <p> with different optional elements and keep the order in which they are.

Can you tell me if this is a bug from the library or from my own code? Can achieve what I want to do by some other way?

Thank you!

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions