JSON field names customisation approaches

Is there a macro, a property wrapper, or similar magic to customise JSON field names without introducing a wholesale CodingKeys? Something like:

struct S: Codable {
    var a, b, c, ... many fields those are fine
    @json("xyz") var x: Int
}

var s = S(a:1, b: 2, ...,  x: 100) // still `x` here
s.x // still `x` here

/*
JSON: {
    "a": 1, "b": 2, ... "xyz" : 100 // `xyz` here
}
*/

Built-in to/from snake conversions are quite fragile :-(
struct S: Codable, Equatable {
    var XYZ: Int = 5
}
let original = S()

let encoder = JSONEncoder()
let decoder = JSONDecoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
decoder.keyDecodingStrategy = .convertFromSnakeCase

let encoded = try encoder.encode(original)
let string = String(data: encoded, encoding: .utf8)!
print("encoded: ", string) // {"x_yz":5}
let decoded = try! decoder.decode(S.self, from: encoded) // Error
print("decoded:", decoded)
1 Like

without a macro, i think its not possible because in the property wrapper you need to provide the string in init(decoder:) which isn’t possible afaict because the property wrapper init used to specify the string is distinct

is using a raw string a requirement?

its a bit more boilerplate but how about something like @JSON(named: \.myCustomName) instead of a raw string?

that can be done if you specify the key as a separate entity (just a single coding key instread of them all)…

i have a working example if that works out…