Skip to content

Encoding/decoding a predicate with recursive option omits optional key paths #1356

Open
@Skoti

Description

@Skoti

Encoding/decoding a predicate:

let predicate = #Predicate<Person> {
    $0.address?.street == "Street"
} 

with configuration:

var config = Predicate<Person>.EncodingConfiguration.standardConfiguration
config.allowKeyPathsForPropertiesProvided(by: Person.self, recursive: true)

fails with:

Caught error: invalidValue(\Address.street, Swift.EncodingError.Context(codingPath: [PredicateExpressionCodingKeys(stringValue: "expression", intValue: nil), _CodingKey(stringValue: "Index 0", intValue: 0), _CodingKey(stringValue: "Index 1", intValue: 1)], debugDescription: "The '\Address.street' keypath is not in the provided allowlist", underlyingError: nil))

Unless I manually add:
config.allowKeyPathsForPropertiesProvided(by: Address.self)
Seems like recursive: true omits optional key paths.

Setup to Reproduce

struct Person: PredicateCodableKeyPathProviding {
    static let predicateCodableKeyPaths: [String: any PartialKeyPath<Person> & Sendable] = [
        "address": \Self.address
    ]

    let address: Address?
}
struct Address: PredicateCodableKeyPathProviding {
    static let predicateCodableKeyPaths: [String: any PartialKeyPath<Address> & Sendable] = [
        "street": \Self.street,
    ]

    let street: String
}
let data = try JSONEncoder().encode(predicate, configuration: config)

Mind that, the same setup with non-optional let address: Address field, works fine with just one configuration call:
config.allowKeyPathsForPropertiesProvided(by: Person.self, recursive: true).

Expected behavior
recursive: true should handle optional fields.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions