commit
34dde6d299
|
@ -0,0 +1,84 @@
|
|||
// MARK: - Keyed Container
|
||||
|
||||
extension KeyedDecodingContainer {
|
||||
public func decode<T, V>(_ type: Failable<T, V>.Type, forKey key: K) throws -> Failable<T, V> where T: Decodable {
|
||||
let wrapped = try self.decode(T.self, forKey: key)
|
||||
return try .init(wrapped)
|
||||
}
|
||||
|
||||
public func decode<T, V>(_ type: Failable<T?, V>.Type, forKey key: K) throws -> Failable<T?, V> where T: Decodable {
|
||||
let wrapped = try self.decodeIfPresent(T.self, forKey: key)
|
||||
return try .init(wrapped)
|
||||
}
|
||||
}
|
||||
|
||||
extension KeyedEncodingContainer {
|
||||
public mutating func encode<T, V>(_ value: Failable<T, V>, forKey key: K) throws where T: Encodable {
|
||||
try self.encode(value.value, forKey: key)
|
||||
}
|
||||
|
||||
public mutating func encode<T, V>(_ value: Failable<T?, V>, forKey key: K) throws where T: Encodable {
|
||||
try self.encodeIfPresent(value.value, forKey: key)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Unkeyed Container
|
||||
|
||||
extension UnkeyedDecodingContainer {
|
||||
public mutating func decode<T, V>(_ type: Failable<T, V>.Type) throws -> Failable<T, V> where T: Decodable {
|
||||
let wrapped = try self.decode(T.self)
|
||||
return try .init(wrapped)
|
||||
}
|
||||
|
||||
public mutating func decode<T, V>(_ type: Failable<T?, V>.Type) throws -> Failable<T?, V> where T: Decodable {
|
||||
let wrapped = try self.decodeIfPresent(T.self)
|
||||
return try .init(wrapped)
|
||||
}
|
||||
}
|
||||
|
||||
extension UnkeyedEncodingContainer {
|
||||
public mutating func encode<T, V>(_ value: Failable<T, V>) throws where T: Encodable {
|
||||
try self.encode(value.value)
|
||||
}
|
||||
|
||||
public mutating func encode<T, V>(_ value: Failable<T?, V>) throws where T: Encodable {
|
||||
if value.value == nil {
|
||||
try self.encodeNil()
|
||||
} else {
|
||||
try self.encode(value.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: Single Value Container
|
||||
|
||||
extension SingleValueDecodingContainer {
|
||||
public func decode<T, V>(_ type: Failable<T, V>.Type) throws -> Failable<T, V> where T: Decodable {
|
||||
let wrapped = try self.decode(T.self)
|
||||
return try .init(wrapped)
|
||||
}
|
||||
|
||||
public func decode<T, V>(_ type: Failable<T?, V>.Type) throws -> Failable<T?, V> where T: Decodable {
|
||||
if self.decodeNil() {
|
||||
return try .init(nil)
|
||||
} else {
|
||||
let wrapped = try self.decode(T.self)
|
||||
return try .init(wrapped)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension SingleValueEncodingContainer {
|
||||
public mutating func encode<T, V>(_ value: Failable<T, V>) throws where T: Encodable {
|
||||
try self.encode(value.value)
|
||||
}
|
||||
|
||||
public mutating func encode<T, V>(_ value: Failable<T?, V>) throws where T: Encodable {
|
||||
if value.value == nil {
|
||||
try self.encodeNil()
|
||||
} else {
|
||||
try self.encode(value.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -12,6 +12,17 @@ extension Failable: Decodable where T: Decodable {
|
|||
/// See [`Decodable.init(from:)`](https://developer.apple.com/documentation/swift/decodable/2894081-init)
|
||||
public init(from decoder: Decoder)throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
try self.init(container.decode(T.self))
|
||||
|
||||
guard _isOptional(T.self) else {
|
||||
try self.init(try container.decode(T.self))
|
||||
return
|
||||
}
|
||||
|
||||
guard container.decodeNil() else {
|
||||
try self.init(try container.decode(T.self))
|
||||
return
|
||||
}
|
||||
|
||||
try self.init(Void?.none as! T)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,15 @@ public func == <T, V1, V2>(lhs: Failable<T, V1>, rhs: Failable<T, V2>) -> Bool w
|
|||
return lhs.value == rhs.value
|
||||
}
|
||||
|
||||
/// Checks for equality of the `value` property from one `Failable` instances with another value of type `T`.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - lhs: The `Failable` instance to compare.
|
||||
/// - rhs: The `T` value to compare.
|
||||
public func == <T, V1>(lhs: Failable<T, V1>, rhs: T) -> Bool where T: Equatable {
|
||||
return lhs.value == rhs
|
||||
}
|
||||
|
||||
/// Checks for inequality of the `value` property from two `Failable` instances where type `T` is the same and comforms to `Equatable`,
|
||||
/// but the `Validations` are different.
|
||||
///
|
||||
|
@ -28,6 +37,15 @@ public func != <T, V1, V2>(lhs: Failable<T, V1>, rhs: Failable<T, V2>) -> Bool w
|
|||
return lhs.value != rhs.value
|
||||
}
|
||||
|
||||
/// Checks for inequality of the `value` property from one `Failable` instances with another value of type `T`.
|
||||
///
|
||||
/// - Parameters:
|
||||
/// - lhs: The `Failable` instance to compare.
|
||||
/// - rhs: The `T` value to compare.
|
||||
public func != <T, V1>(lhs: Failable<T, V1>, rhs: T) -> Bool where T: Equatable {
|
||||
return lhs.value != rhs
|
||||
}
|
||||
|
||||
// MARK: - Comparable
|
||||
|
||||
extension Failable: Comparable where T: Comparable {
|
||||
|
|
Loading…
Reference in New Issue