makoni/parsable
`Parsable` is a small Swift library that adds lightweight JSON encoding and decoding helpers to any `Codable` model.
What it does
- Keeps conformance lightweight:
extension Model: Parseable {} - Provides primary throwing APIs for decoding and encoding
- Supports configured
JSONDecoderandJSONEncoderinstances - Keeps the original nil-returning helpers for compatibility
- Lets you configure or disable compatibility-helper logging
Installation
Swift Package Manager
Add Parsable to the dependencies section of your Package.swift:
dependencies: [
.package(url: "https://github.com/makoni/parsable.git", from: "1.0.0"),
]Quick start
import Foundation
import Parsable
struct APIError: Codable {
let error: String
let code: Int
let date: Date
}
extension APIError: Parseable {}
let jsonData = Data("{\"error\":\"Not Found\",\"code\":404,\"date\":1713171900}".utf8)
let decodedError = try APIError.decode(from: jsonData)
let encodedError = try decodedError.encoded()Primary API
Use the throwing APIs when you want the underlying encoding or decoding error:
let decodedModel = try APIError.decode(from: jsonData)
let encodedData = try decodedModel.encoded()For Unix timestamps in milliseconds:
let decodedModel = try APIError.decode(
from: jsonData,
dateDecodingStrategy: .millisecondsSince1970
)
let encodedData = try decodedModel.encoded(
dateEncodingStrategy: .millisecondsSince1970
)Using a configured decoder or encoder
If you need key strategies or any other JSONDecoder / JSONEncoder configuration, pass your own instance:
struct APIResponse: Codable {
let errorMessage: String
let statusCode: Int
}
extension APIResponse: Parseable {}
let decoder = JSONDecoder()
decoder.keyDecodingStrategy = .convertFromSnakeCase
let responseData = Data("{\"error_message\":\"Not Found\",\"status_code\":404}".utf8)
let response = try APIResponse.decode(from: responseData, using: decoder)
let encoder = JSONEncoder()
encoder.keyEncodingStrategy = .convertToSnakeCase
let encodedResponse = try response.encoded(using: encoder)Compatibility helpers
The original API is still available as deprecated nil-returning convenience methods:
let decodedModel = APIError.decodeFromData(data: jsonData)
let encodedData = APIError.encode(fromEncodable: APIError(error: "Not Found", code: 404, date: .now))Those helpers return nil and forward failures to ParsableConfiguration.failureLogger when logging is enabled. Prefer the throwing APIs in new code when you need to inspect errors.
Compatibility helper logging
Deprecated compatibility helpers log failures through ParsableConfiguration.failureLogger, which is enabled by default.
ParsableConfiguration.failureLogger = { error, context in
print("Parsable warning: \(context.file):\(context.line) \(error.localizedDescription)")
}
ParsableConfiguration.disableFailureLogging()
ParsableConfiguration.enableDefaultFailureLogging()Documentation
Hosted documentation: https://spaceinbox.me/docs/parsable/documentation/parsable/
The DocC source lives in Sources/Parsable/Documentation.docc.
Package Metadata
Repository: makoni/parsable
Default branch: master
README: README.md