Skip to content

Decoding containers with (potentially)-empty elements #123

@jsbean

Description

@jsbean

We have a use case where we need to decode an array of potentially empty elements.

Currently, unkeyed and keyed containers holding onto empty (e.g., a struct with no fields) or a potentially empty (e.g., a struct with all optional fields) elements does not decode.

Say we've got a struct like this:

struct Empty: Equatable, Codable { }

If we have some XML like this:

let xml = """
<container>
    <empty/>
    <empty/>
    <empty/>
</container>
"""

It would be nice to decode like this:

let decoded = try XMLDecoder().decode([Empty].self, from: xml.data(using: .utf8)!)
// Throws "Expected Empty but found null instead."

The poetics are strong.

Wrapping it up a bit, consider this:

struct EmptyArray: Equatable, Codable {
    enum CodingKeys: String, CodingKey { case empties = "empty" }
    let empties: [Empty]
}

Given the xml from above, we can try to decode it like this:

let decoded = try XMLDecoder().decode(EmptyArray.self, from: xml.data(using: .utf8)!)
// Throws "Expected Array<Empty> value but found null instead."

Lastly, given this container:

struct EmptyWrapper {
    let empty: Empty
}

And we have some XML like this:

let xml = """
<wrapper>
    <empty/>
</wrapper>
"""

And we try to decode it like this:

let decoded = try XMLDecoder().decode(EmptyWrapper.self, from: xml.data(using: .utf8)!)
// Throws "Expected Empty value but found null instead"

We get the same outcomes if you substitute the Empty type with something like this:

struct MaybeEmpty {
    var idunno: Int?
}

If this seems like something that should theoretically be supported, I can give a go at it. It smells like it might touch similar neighborhoods of the codebase as #122.

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