Skip to content

AnyCodable cannot encode types conforming to Encodable #417

@true-false-maybe

Description

@true-false-maybe

While trying to write some Codable-Types, to make some Vendor extensions from eg https://redocly.com/docs/redoc/redoc-vendor-extensions#x-logo type-safe(-r), i noticed this is not really possible. Writing this code seems like it should work, but it doesn't:

...
vendorExtensions: [
    "x-logo": AnyCodable(VendorExtensions.Logo(
        url: "https://example.com/logo.png",
        backgroundColor: "#FFFFFF",
        altText: "logo"
    ))
]

where VendorExtensions.Logo is:

public enum VendorExtensions {
    /// Logo as described in https://redocly.com/docs/redoc/redoc-vendor-extensions#logo-object
    public struct Logo: Codable {
        /// The URL pointing to the spec logo. MUST be in the format of a URL. It SHOULD be an absolute URL so your API definition is usable from any location
        let url: String
        /// background color to be used. MUST be RGB color in [hexadecimal format]
        let backgroundColor: String
        /// Text to use for alt tag on the logo. Defaults to 'logo' if nothing is provided.
        let altText: String?
        /// The URL pointing to the contact page. Default to 'info.contact.url' field of the OAS.
        let href: String?

        /// Create a logo as described in https://redocly.com/docs/redoc/redoc-vendor-extensions#logo-object
        /// - Parameters:
        ///   - url: the URL pointing to the spec logo. MUST be in the format of a URL. It SHOULD be an absolute URL so your API definition is usable from any location
        ///   - backgroundColor: background color to be used. MUST be RGB color in [hexadecimal format]
        ///   - altText: text to use for alt tag on the logo. Defaults to 'logo' if nothing is provided.
        ///   - href: the URL pointing to the contact page. Default to 'info.contact.url' field of the OAS.
        init(url: String, backgroundColor: String, altText: String? = nil, href: String? = nil) {
            self.url = url
            self.backgroundColor = backgroundColor
            self.altText = altText
            self.href = href
        }
    }
}

it fails with the message:

invalidValue(Documentation.VendorExtensions.Logo(url: "https://example.com/logo.png", backgroundColor: "#FFFFFF", altText: Optional("logo"), href: nil), Swift.EncodingError.Context(codingPath: [CodingKeys(stringValue: "info", intValue: nil), CodingKeys(stringValue: "x-logo", intValue: nil)], debugDescription: "AnyCodable value cannot be encoded", underlyingError: nil))

specifically: AnyCodable value cannot be encoded

i propose to add support for types which conform to Encodable. This also helps specifying examples in a type-safe way i would think. The only down-side is that the type-safety will obviously be gone when encoding and decoding the same file, but the way it's currently that information was never there, so it's not really a downside imo.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions