Skip to content

Instantly share code, notes, and snippets.

@MojtabaHs
Last active June 17, 2022 15:16
Show Gist options
  • Save MojtabaHs/a8c19aea78c01ffc3063745dbbc10df1 to your computer and use it in GitHub Desktop.
Save MojtabaHs/a8c19aea78c01ffc3063745dbbc10df1 to your computer and use it in GitHub Desktop.
Decode logical `Bool` into a real `Bool` with this simple Property Wrapper.
// MARK: - Wrapper
@propertyWrapper
struct SomeKindOfBool: Decodable {
var wrappedValue: Bool
init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
if let stringifiedValue = try? container.decode(String.self) {
switch stringifiedValue.lowercased() {
case "false", "no", "0", "n", "f": wrappedValue = false
case "true", "yes", "1", "y", "t": wrappedValue = true
default: throw DecodeError.unknownString(stringifiedValue) /* You can handle other Strings here if you want */
}
} else if let integerifiedValue = try? container.decode(Int.self) {
switch integerifiedValue {
case 0: wrappedValue = false
case 1: wrappedValue = true
default: throw DecodeError.unknownInteger(integerifiedValue) /* You can handle other Integers here if you want */
}
} else {
wrappedValue = try container.decode(Bool.self)
}
}
}
// MARK: - Errors
enum DecodeError: Error {
case unknownString(String)
case unknownInteger(Int)
}
/*
#Usage
struct MyType: Decodable {
@SomeKindOfBool var someKey: Bool
}
#Test
let jsonData = """
[
{ "someKey": 1 },
{ "someKey": "true" },
{ "someKey": true }
]
""".data(using: .utf8)!
let decodedJSON = try! JSONDecoder().decode([MyType].self, from: jsonData)
for decodedType in decodedJSON {
print(decodedType.someKey)
}
*/
@ptrkstr
Copy link

ptrkstr commented Jun 24, 2021

I would suggest using an existing DecodingError so the container and key can be passed up, i.e:

throw DecodingError.dataCorruptedError(in: container, debugDescription: "Expected `0` or `1` but received `\(intValue)`")

This is what I used in my answer here: https://stackoverflow.com/a/68101019/4698501

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment