64 lines
2.1 KiB
Swift
64 lines
2.1 KiB
Swift
import Foundation
|
|
|
|
/// A type-erased JSON value that preserves the raw JSON for domain-specific decoding.
|
|
public struct RawJSON: Codable, Hashable, Sendable {
|
|
public let value: JSONValue
|
|
|
|
public init(value: JSONValue) {
|
|
self.value = value
|
|
}
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
self.value = try container.decode(JSONValue.self)
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
try container.encode(value)
|
|
}
|
|
}
|
|
|
|
/// Recursive JSON value type for generic content.
|
|
public indirect enum JSONValue: Codable, Hashable, Sendable {
|
|
case string(String)
|
|
case number(Double)
|
|
case bool(Bool)
|
|
case null
|
|
case array([JSONValue])
|
|
case object([String: JSONValue])
|
|
|
|
public init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
if let str = try? container.decode(String.self) {
|
|
self = .string(str)
|
|
} else if let bool = try? container.decode(Bool.self) {
|
|
self = .bool(bool)
|
|
} else if let num = try? container.decode(Double.self) {
|
|
self = .number(num)
|
|
} else if container.decodeNil() {
|
|
self = .null
|
|
} else if let arr = try? container.decode([JSONValue].self) {
|
|
self = .array(arr)
|
|
} else if let obj = try? container.decode([String: JSONValue].self) {
|
|
self = .object(obj)
|
|
} else {
|
|
throw DecodingError.dataCorruptedError(
|
|
in: container,
|
|
debugDescription: "Unsupported JSON value"
|
|
)
|
|
}
|
|
}
|
|
|
|
public func encode(to encoder: Encoder) throws {
|
|
var container = encoder.singleValueContainer()
|
|
switch self {
|
|
case .string(let s): try container.encode(s)
|
|
case .number(let n): try container.encode(n)
|
|
case .bool(let b): try container.encode(b)
|
|
case .null: try container.encodeNil()
|
|
case .array(let a): try container.encode(a)
|
|
case .object(let o): try container.encode(o)
|
|
}
|
|
}
|
|
}
|