-
Notifications
You must be signed in to change notification settings - Fork 14
/
IgnoredKey.swift
73 lines (60 loc) · 2.41 KB
/
IgnoredKey.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//
// IgnoredKey.swift
// CodableExample
//
// Created by Condy on 2024/6/18.
//
import Foundation
/// Add this to an Optional Property to not included it when Encoding or Decoding
@propertyWrapper public struct IgnoredKey<T: Codable>: OmitableFromEncoding & OmitableFromDecoding {
public var wrappedValue: T?
public init(wrappedValue: T?) {
self.wrappedValue = wrappedValue
}
}
@propertyWrapper public struct IgnoredKeyEncoding<T: Encodable>: OmitableFromEncoding {
public var wrappedValue: T?
public init(wrappedValue: T?) {
self.wrappedValue = wrappedValue
}
}
@propertyWrapper public struct IgnoredKeyDecoding<T: Decodable>: OmitableFromDecoding {
public var wrappedValue: T?
public init(wrappedValue: T?) {
self.wrappedValue = wrappedValue
}
}
extension KeyedDecodingContainer {
// This is used to override the default decoding behavior for OptionalCodingWrapper to allow a value to avoid a missing key Error
public func decode<T>(_ type: T.Type, forKey key: KeyedDecodingContainer<K>.Key) throws -> T where T: OmitableFromDecoding {
return try decodeIfPresent(T.self, forKey: key) ?? T(wrappedValue: nil)
}
}
extension KeyedEncodingContainer {
// Used to make make sure OmitableFromEncoding never encodes a value
public mutating func encode<T>(_ value: T, forKey key: KeyedEncodingContainer<K>.Key) throws where T: OmitableFromEncoding {
return
}
}
public protocol OmitableFromEncoding: Encodable { }
extension OmitableFromEncoding {
// This shouldn't ever be called since KeyedEncodingContainer should skip it due to the included extension
public func encode(to encoder: Encoder) throws { return }
}
public protocol OmitableFromDecoding: Decodable {
associatedtype T: ExpressibleByNilLiteral
init(wrappedValue: T)
}
extension OmitableFromDecoding {
public init(from decoder: Decoder) throws {
self.init(wrappedValue: nil)
}
}
extension IgnoredKeyEncoding: Decodable where T: Decodable { }
extension IgnoredKeyDecoding: Encodable where T: Encodable { }
extension IgnoredKeyEncoding: Equatable where T: Equatable { }
extension IgnoredKeyDecoding: Equatable where T: Equatable { }
extension IgnoredKey: Equatable where T: Equatable { }
extension IgnoredKeyEncoding: Hashable where T: Hashable { }
extension IgnoredKeyDecoding: Hashable where T: Hashable { }
extension IgnoredKey: Hashable where T: Hashable { }