@procivis/react-native-one-core 1.41710.0 → 1.43299.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/ch/procivis/one/core/DeserializeSpecific.kt +1 -1
- package/android/src/main/java/ch/procivis/one/core/ProcivisOneCoreModule.kt +37 -4
- package/android/src/main/java/ch/procivis/one/core/Serialize.kt +3 -1
- package/android/src/main/java/ch/procivis/one/core/SerializeSpecific.kt +13 -0
- package/core-sdk.json +6 -6
- package/dist/src/config.d.ts +3 -1
- package/dist/src/core.d.ts +9 -3
- package/dist/src/core.js +5 -0
- package/dist/src/credential.d.ts +6 -2
- package/dist/src/history.d.ts +5 -2
- package/dist/src/history.js +3 -0
- package/dist/src/identifier.d.ts +132 -0
- package/dist/src/identifier.js +29 -0
- package/dist/src/proof.d.ts +9 -4
- package/ios/Deserialize.swift +140 -813
- package/ios/EventEmitter.swift +84 -72
- package/ios/ProcivisOneCoreModule.m +19 -1
- package/ios/ProcivisOneCoreModule.swift +986 -806
- package/ios/ProcivisRNOneCore.xcodeproj/project.pbxproj +9 -1
- package/ios/RNDecoder/RNDecoder.swift +191 -0
- package/ios/RNDecoder/RNDecodingStorage.swift +33 -0
- package/ios/RNDecoder/RNKeyedDecodingContainer.swift +133 -0
- package/ios/RNDecoder/RNUnkeyedDecodingContainer.swift +175 -0
- package/ios/RNEncoder/RNAnyCodingKey.swift +31 -0
- package/ios/RNEncoder/RNEncoder.swift +95 -0
- package/ios/RNEncoder/RNKeyedEncodingContainer.swift +81 -0
- package/ios/RNEncoder/RNSingleValueEncodingContainer.swift +78 -0
- package/ios/RNEncoder/RNUnkeyedEncodingContainer.swift +84 -0
- package/ios/Serialize.swift +43 -613
- package/ios/Util.swift +35 -25
- package/package.json +2 -2
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
archiveVersion = 1;
|
|
4
4
|
classes = {
|
|
5
5
|
};
|
|
6
|
-
objectVersion =
|
|
6
|
+
objectVersion = 70;
|
|
7
7
|
objects = {
|
|
8
8
|
|
|
9
9
|
/* Begin PBXBuildFile section */
|
|
@@ -49,6 +49,10 @@
|
|
|
49
49
|
33F2711A292F97400090E4DB /* ProcivisOneCoreModule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProcivisOneCoreModule.swift; sourceTree = "<group>"; };
|
|
50
50
|
/* End PBXFileReference section */
|
|
51
51
|
|
|
52
|
+
/* Begin PBXFileSystemSynchronizedRootGroup section */
|
|
53
|
+
33CF268B2CB97A5700E95B65 /* RNEncoder */ = {isa = PBXFileSystemSynchronizedRootGroup; explicitFileTypes = {}; explicitFolders = (); path = RNEncoder; sourceTree = "<group>"; };
|
|
54
|
+
/* End PBXFileSystemSynchronizedRootGroup section */
|
|
55
|
+
|
|
52
56
|
/* Begin PBXFrameworksBuildPhase section */
|
|
53
57
|
58B511D81A9E6C8500147676 /* Frameworks */ = {
|
|
54
58
|
isa = PBXFrameworksBuildPhase;
|
|
@@ -79,6 +83,7 @@
|
|
|
79
83
|
15260DEB2D561D7F00797D80 /* RSEPinPadManager.m */,
|
|
80
84
|
15260DE92D561D6900797D80 /* RSEKeyStorage.swift */,
|
|
81
85
|
15260DE72D561D4300797D80 /* UBQKit.xcframework */,
|
|
86
|
+
33CF268B2CB97A5700E95B65 /* RNEncoder */,
|
|
82
87
|
33F27119292F97400090E4DB /* ProcivisOneCoreModule.m */,
|
|
83
88
|
339DE1312A4EB16300F68DE2 /* ProcivisOneCore.xcframework */,
|
|
84
89
|
33F2711A292F97400090E4DB /* ProcivisOneCoreModule.swift */,
|
|
@@ -105,6 +110,9 @@
|
|
|
105
110
|
);
|
|
106
111
|
dependencies = (
|
|
107
112
|
);
|
|
113
|
+
fileSystemSynchronizedGroups = (
|
|
114
|
+
33CF268B2CB97A5700E95B65 /* RNEncoder */,
|
|
115
|
+
);
|
|
108
116
|
name = ProcivisRNOneCore;
|
|
109
117
|
productName = RCTDataManager;
|
|
110
118
|
productReference = 134814201AA4EA6300B7C361 /* libProcivisRNOneCore.a */;
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public typealias CustomDecoder = (_ value: Any, _ type: Any.Type, _ codingPath: [CodingKey]) throws
|
|
4
|
+
-> Any?
|
|
5
|
+
public let customDecoderKey = CodingUserInfoKey(rawValue: "customDecoder")!
|
|
6
|
+
|
|
7
|
+
final public class RNDecoder {
|
|
8
|
+
public init() {}
|
|
9
|
+
|
|
10
|
+
public var userInfo: [CodingUserInfoKey: Any] = [:]
|
|
11
|
+
|
|
12
|
+
public func decode<T: Decodable>(_ value: Any) throws -> T {
|
|
13
|
+
return try decode(T.self, from: value)
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
public func decode<T: Decodable>(_ type: T.Type, from data: Any) throws -> T {
|
|
17
|
+
let decoder = RNInternalDecoder(referencing: data, userInfo: self.userInfo)
|
|
18
|
+
|
|
19
|
+
guard let value = try decoder.unbox(data, as: type) else {
|
|
20
|
+
throw DecodingError.valueNotFound(
|
|
21
|
+
type,
|
|
22
|
+
DecodingError.Context(
|
|
23
|
+
codingPath: [],
|
|
24
|
+
debugDescription: "The given data did not contain a top-level value."
|
|
25
|
+
)
|
|
26
|
+
)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return value
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// MARK: - TopLevelDecoder
|
|
34
|
+
|
|
35
|
+
#if canImport(Combine)
|
|
36
|
+
import Combine
|
|
37
|
+
|
|
38
|
+
extension RNDecoder: TopLevelDecoder {
|
|
39
|
+
public typealias Input = Any
|
|
40
|
+
}
|
|
41
|
+
#endif
|
|
42
|
+
|
|
43
|
+
// MARK: -
|
|
44
|
+
|
|
45
|
+
class RNInternalDecoder {
|
|
46
|
+
internal var storage: RNDecodingStorage
|
|
47
|
+
internal let userInfo: [CodingUserInfoKey: Any]
|
|
48
|
+
internal(set) public var codingPath: [CodingKey]
|
|
49
|
+
|
|
50
|
+
internal init(
|
|
51
|
+
referencing container: Any,
|
|
52
|
+
at codingPath: [CodingKey] = [],
|
|
53
|
+
userInfo: [CodingUserInfoKey: Any]
|
|
54
|
+
) {
|
|
55
|
+
self.storage = RNDecodingStorage()
|
|
56
|
+
self.storage.push(container: container)
|
|
57
|
+
self.codingPath = codingPath
|
|
58
|
+
self.userInfo = userInfo
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
extension RNInternalDecoder: Decoder {
|
|
63
|
+
func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key>
|
|
64
|
+
where Key: CodingKey {
|
|
65
|
+
guard !(self.storage.topContainer is NSNull) else {
|
|
66
|
+
throw DecodingError.valueNotFound(
|
|
67
|
+
KeyedDecodingContainer<Key>.self,
|
|
68
|
+
DecodingError.Context(
|
|
69
|
+
codingPath: self.codingPath,
|
|
70
|
+
debugDescription: "Cannot get keyed decoding container -- found null value instead."
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
guard let topContainer = self.storage.topContainer as? [String: Any] else {
|
|
76
|
+
let description =
|
|
77
|
+
"Expected to decode \([String : Any].self) but found '\(self.storage.topContainer)' instead."
|
|
78
|
+
throw DecodingError.typeMismatch(
|
|
79
|
+
[String: Any].self,
|
|
80
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let container = RNKeyedDecodingContainer<Key>(referencing: self, wrapping: topContainer)
|
|
85
|
+
return KeyedDecodingContainer(container)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
func unkeyedContainer() throws -> any UnkeyedDecodingContainer {
|
|
89
|
+
guard !(self.storage.topContainer is NSNull) else {
|
|
90
|
+
throw DecodingError.valueNotFound(
|
|
91
|
+
UnkeyedDecodingContainer.self,
|
|
92
|
+
DecodingError.Context(
|
|
93
|
+
codingPath: self.codingPath,
|
|
94
|
+
debugDescription: "Cannot get unkeyed decoding container -- found null value instead."
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
let topContainer: [Any]
|
|
100
|
+
|
|
101
|
+
if let container = self.storage.topContainer as? [Any] {
|
|
102
|
+
topContainer = container
|
|
103
|
+
} else if let container = self.storage.topContainer as? [AnyHashable: Any] {
|
|
104
|
+
topContainer = [container]
|
|
105
|
+
} else {
|
|
106
|
+
let description =
|
|
107
|
+
"Expected to decode \([Any].self) but found '\(self.storage.topContainer)' instead."
|
|
108
|
+
throw DecodingError.typeMismatch(
|
|
109
|
+
[Any].self,
|
|
110
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return RNUnkeyedDecodingContainer(referencing: self, wrapping: topContainer)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
public func singleValueContainer() throws -> SingleValueDecodingContainer {
|
|
118
|
+
return self
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
extension RNInternalDecoder: SingleValueDecodingContainer {
|
|
123
|
+
private func expectNonNull<T>(_ type: T.Type) throws {
|
|
124
|
+
guard !self.decodeNil() else {
|
|
125
|
+
throw DecodingError.valueNotFound(
|
|
126
|
+
type,
|
|
127
|
+
DecodingError.Context(
|
|
128
|
+
codingPath: self.codingPath,
|
|
129
|
+
debugDescription: "Expected \(type) but found null value instead."
|
|
130
|
+
)
|
|
131
|
+
)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
public func decodeNil() -> Bool {
|
|
136
|
+
return self.storage.topContainer is NSNull
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
public func decode<T: Decodable>(_ type: T.Type) throws -> T {
|
|
140
|
+
try expectNonNull(type)
|
|
141
|
+
return try self.unbox(self.storage.topContainer, as: type)!
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
extension RNInternalDecoder {
|
|
146
|
+
internal func unbox<T: Decodable>(_ value: Any, as type: T.Type) throws -> T? {
|
|
147
|
+
if let customDecoder = self.userInfo[customDecoderKey] {
|
|
148
|
+
if let result = try (customDecoder as! CustomDecoder)(value, type, self.codingPath) {
|
|
149
|
+
return (result as! T)
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
if type == String.self || type == Bool.self || type is any Numeric.Type {
|
|
154
|
+
guard let data = value as? T else {
|
|
155
|
+
let description = "Expected to decode \(type) but found '\(value)' instead."
|
|
156
|
+
throw DecodingError.typeMismatch(
|
|
157
|
+
type,
|
|
158
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
return data
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
if let enumType = type as? any CaseIterable.Type {
|
|
165
|
+
guard let data = value as? String else {
|
|
166
|
+
let description = "Expected to decode \(type) but found '\(value)' instead."
|
|
167
|
+
throw DecodingError.typeMismatch(
|
|
168
|
+
type,
|
|
169
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
170
|
+
)
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
let match = enumType.allCases.first {
|
|
174
|
+
return serializeEnumValue(value: $0) == data
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
guard let result = match as? T else {
|
|
178
|
+
let description = "Expected to decode \(type) but found '\(value)' instead."
|
|
179
|
+
throw DecodingError.typeMismatch(
|
|
180
|
+
type,
|
|
181
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
182
|
+
)
|
|
183
|
+
}
|
|
184
|
+
return result
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
self.storage.push(container: value)
|
|
188
|
+
defer { self.storage.popContainer() }
|
|
189
|
+
return try type.init(from: self)
|
|
190
|
+
}
|
|
191
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
internal struct RNDecodingStorage {
|
|
4
|
+
// MARK: Properties
|
|
5
|
+
|
|
6
|
+
/// The container stack.
|
|
7
|
+
private(set) internal var containers: [Any] = []
|
|
8
|
+
|
|
9
|
+
// MARK: - Initialization
|
|
10
|
+
|
|
11
|
+
/// Initializes `self` with no containers.
|
|
12
|
+
internal init() {}
|
|
13
|
+
|
|
14
|
+
// MARK: - Modifying the Stack
|
|
15
|
+
|
|
16
|
+
internal var count: Int {
|
|
17
|
+
return self.containers.count
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
internal var topContainer: Any {
|
|
21
|
+
precondition(!self.containers.isEmpty, "Empty container stack.")
|
|
22
|
+
return self.containers.last!
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
internal mutating func push(container: Any) {
|
|
26
|
+
self.containers.append(container)
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
internal mutating func popContainer() {
|
|
30
|
+
precondition(!self.containers.isEmpty, "Empty container stack.")
|
|
31
|
+
self.containers.removeLast()
|
|
32
|
+
}
|
|
33
|
+
}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
internal class RNKeyedDecodingContainer<Key: CodingKey> {
|
|
4
|
+
private let decoder: RNInternalDecoder
|
|
5
|
+
private let container: [String: Any]
|
|
6
|
+
private(set) public var codingPath: [CodingKey]
|
|
7
|
+
|
|
8
|
+
internal init(referencing decoder: RNInternalDecoder, wrapping container: [String: Any]) {
|
|
9
|
+
self.decoder = decoder
|
|
10
|
+
self.container = container
|
|
11
|
+
self.codingPath = decoder.codingPath
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
extension RNKeyedDecodingContainer: KeyedDecodingContainerProtocol {
|
|
16
|
+
public var allKeys: [Key] {
|
|
17
|
+
return self.container.keys.compactMap { Key(stringValue: $0) }
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
public func contains(_ key: Key) -> Bool {
|
|
21
|
+
return self.container[key.stringValue] != nil
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public func decodeNil(forKey key: Key) throws -> Bool {
|
|
25
|
+
return !self.contains(key)
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
private func _errorDescription(of key: CodingKey) -> String {
|
|
29
|
+
return "\(key) (\"\(key.stringValue)\")"
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
func decode<T: Decodable>(_ type: T.Type, forKey key: Key) throws -> T {
|
|
33
|
+
guard let entry = self.container[key.stringValue] else {
|
|
34
|
+
throw DecodingError.keyNotFound(
|
|
35
|
+
key,
|
|
36
|
+
DecodingError.Context(
|
|
37
|
+
codingPath: self.decoder.codingPath,
|
|
38
|
+
debugDescription: "No value associated with key \(_errorDescription(of: key))."
|
|
39
|
+
)
|
|
40
|
+
)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
self.decoder.codingPath.append(key)
|
|
44
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
45
|
+
|
|
46
|
+
guard let value = try self.decoder.unbox(entry, as: type) else {
|
|
47
|
+
throw DecodingError.valueNotFound(
|
|
48
|
+
type,
|
|
49
|
+
DecodingError.Context(
|
|
50
|
+
codingPath: self.decoder.codingPath,
|
|
51
|
+
debugDescription: "Expected \(type) value but found null instead."
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
return value
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type, forKey key: Key) throws
|
|
60
|
+
-> KeyedDecodingContainer<NestedKey> where NestedKey: CodingKey
|
|
61
|
+
{
|
|
62
|
+
self.decoder.codingPath.append(key)
|
|
63
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
64
|
+
|
|
65
|
+
guard let value = self.container[key.stringValue] else {
|
|
66
|
+
throw DecodingError.keyNotFound(
|
|
67
|
+
key,
|
|
68
|
+
DecodingError.Context(
|
|
69
|
+
codingPath: self.codingPath,
|
|
70
|
+
debugDescription:
|
|
71
|
+
"Cannot get \(KeyedDecodingContainer<NestedKey>.self) -- no value found for key \"\(key.stringValue)\""
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
guard let dictionary = value as? [String: Any] else {
|
|
77
|
+
let description = "Expected to decode \([String : Any].self) but found '\(value)' instead."
|
|
78
|
+
throw DecodingError.typeMismatch(
|
|
79
|
+
[String: Any].self,
|
|
80
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
81
|
+
)
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
let container = RNKeyedDecodingContainer<NestedKey>(
|
|
85
|
+
referencing: self.decoder,
|
|
86
|
+
wrapping: dictionary
|
|
87
|
+
)
|
|
88
|
+
return KeyedDecodingContainer(container)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
func nestedUnkeyedContainer(forKey key: Key) throws -> any UnkeyedDecodingContainer {
|
|
92
|
+
self.decoder.codingPath.append(key)
|
|
93
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
94
|
+
|
|
95
|
+
guard let value = self.container[key.stringValue] else {
|
|
96
|
+
throw DecodingError.keyNotFound(
|
|
97
|
+
key,
|
|
98
|
+
DecodingError.Context(
|
|
99
|
+
codingPath: self.codingPath,
|
|
100
|
+
debugDescription:
|
|
101
|
+
"Cannot get UnkeyedDecodingContainer -- no value found for key \"\(key.stringValue)\""
|
|
102
|
+
)
|
|
103
|
+
)
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
guard let array = value as? [Any] else {
|
|
107
|
+
let description = "Expected to decode \([Any].self) but found '\(value)' instead."
|
|
108
|
+
throw DecodingError.typeMismatch(
|
|
109
|
+
[Any].self,
|
|
110
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
return RNUnkeyedDecodingContainer(referencing: self.decoder, wrapping: array)
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
private func _superDecoder(forKey key: CodingKey) throws -> Decoder {
|
|
118
|
+
let value: Any = self.container[key.stringValue] ?? NSNull()
|
|
119
|
+
return RNInternalDecoder(
|
|
120
|
+
referencing: value,
|
|
121
|
+
at: self.decoder.codingPath + [key],
|
|
122
|
+
userInfo: self.decoder.userInfo
|
|
123
|
+
)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
public func superDecoder() throws -> Decoder {
|
|
127
|
+
fatalError("Unimplemented")
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
public func superDecoder(forKey key: Key) throws -> Decoder {
|
|
131
|
+
return try _superDecoder(forKey: key)
|
|
132
|
+
}
|
|
133
|
+
}
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
internal class RNUnkeyedDecodingContainer {
|
|
4
|
+
private let decoder: RNInternalDecoder
|
|
5
|
+
private let container: [Any]
|
|
6
|
+
private(set) public var codingPath: [CodingKey]
|
|
7
|
+
private(set) public var currentIndex: Int
|
|
8
|
+
|
|
9
|
+
internal init(referencing decoder: RNInternalDecoder, wrapping container: [Any]) {
|
|
10
|
+
self.decoder = decoder
|
|
11
|
+
self.container = container
|
|
12
|
+
self.codingPath = decoder.codingPath
|
|
13
|
+
self.currentIndex = 0
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
extension RNUnkeyedDecodingContainer: UnkeyedDecodingContainer {
|
|
18
|
+
var count: Int? {
|
|
19
|
+
return self.container.count
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
var isAtEnd: Bool {
|
|
23
|
+
return self.currentIndex >= self.container.count
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
func decodeNil() throws -> Bool {
|
|
27
|
+
guard !self.isAtEnd else {
|
|
28
|
+
throw DecodingError.valueNotFound(
|
|
29
|
+
Any?.self,
|
|
30
|
+
DecodingError.Context(
|
|
31
|
+
codingPath: self.decoder.codingPath + [RNAnyCodingKey(intValue: self.currentIndex)],
|
|
32
|
+
debugDescription: "Unkeyed container is at end."
|
|
33
|
+
)
|
|
34
|
+
)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
if self.container[self.currentIndex] is NSNull {
|
|
38
|
+
self.currentIndex += 1
|
|
39
|
+
return true
|
|
40
|
+
} else {
|
|
41
|
+
return false
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
func decode<T: Decodable>(_ type: T.Type) throws -> T {
|
|
46
|
+
guard !self.isAtEnd else {
|
|
47
|
+
throw DecodingError.valueNotFound(
|
|
48
|
+
type,
|
|
49
|
+
DecodingError.Context(
|
|
50
|
+
codingPath: self.decoder.codingPath + [RNAnyCodingKey(intValue: self.currentIndex)],
|
|
51
|
+
debugDescription: "Unkeyed container is at end."
|
|
52
|
+
)
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
self.decoder.codingPath.append(RNAnyCodingKey(intValue: self.currentIndex))
|
|
57
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
58
|
+
|
|
59
|
+
guard let decoded = try self.decoder.unbox(self.container[self.currentIndex], as: type) else {
|
|
60
|
+
throw DecodingError.valueNotFound(
|
|
61
|
+
type,
|
|
62
|
+
DecodingError.Context(
|
|
63
|
+
codingPath: self.decoder.codingPath + [RNAnyCodingKey(intValue: self.currentIndex)],
|
|
64
|
+
debugDescription: "Expected \(type) but found null instead."
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
self.currentIndex += 1
|
|
70
|
+
return decoded
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
func nestedContainer<NestedKey>(keyedBy type: NestedKey.Type) throws -> KeyedDecodingContainer<
|
|
74
|
+
NestedKey
|
|
75
|
+
> where NestedKey: CodingKey {
|
|
76
|
+
self.decoder.codingPath.append(RNAnyCodingKey(intValue: self.currentIndex))
|
|
77
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
78
|
+
|
|
79
|
+
guard !self.isAtEnd else {
|
|
80
|
+
throw DecodingError.valueNotFound(
|
|
81
|
+
KeyedDecodingContainer<NestedKey>.self,
|
|
82
|
+
DecodingError.Context(
|
|
83
|
+
codingPath: self.codingPath,
|
|
84
|
+
debugDescription: "Cannot get nested keyed container -- unkeyed container is at end."
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
let value = self.container[self.currentIndex]
|
|
90
|
+
guard !(value is NSNull) else {
|
|
91
|
+
throw DecodingError.valueNotFound(
|
|
92
|
+
KeyedDecodingContainer<NestedKey>.self,
|
|
93
|
+
DecodingError.Context(
|
|
94
|
+
codingPath: self.codingPath,
|
|
95
|
+
debugDescription: "Cannot get keyed decoding container -- found null value instead."
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
guard let dictionary = value as? [String: Any] else {
|
|
101
|
+
let description = "Expected to decode \([String : Any].self) but found '\(value)' instead."
|
|
102
|
+
throw DecodingError.typeMismatch(
|
|
103
|
+
[String: Any].self,
|
|
104
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
105
|
+
)
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
self.currentIndex += 1
|
|
109
|
+
let container = RNKeyedDecodingContainer<NestedKey>(
|
|
110
|
+
referencing: self.decoder,
|
|
111
|
+
wrapping: dictionary
|
|
112
|
+
)
|
|
113
|
+
return KeyedDecodingContainer(container)
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
func nestedUnkeyedContainer() throws -> any UnkeyedDecodingContainer {
|
|
117
|
+
self.decoder.codingPath.append(RNAnyCodingKey(intValue: self.currentIndex))
|
|
118
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
119
|
+
|
|
120
|
+
guard !self.isAtEnd else {
|
|
121
|
+
throw DecodingError.valueNotFound(
|
|
122
|
+
UnkeyedDecodingContainer.self,
|
|
123
|
+
DecodingError.Context(
|
|
124
|
+
codingPath: self.codingPath,
|
|
125
|
+
debugDescription: "Cannot get nested keyed container -- unkeyed container is at end."
|
|
126
|
+
)
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
let value = self.container[self.currentIndex]
|
|
131
|
+
guard !(value is NSNull) else {
|
|
132
|
+
throw DecodingError.valueNotFound(
|
|
133
|
+
UnkeyedDecodingContainer.self,
|
|
134
|
+
DecodingError.Context(
|
|
135
|
+
codingPath: self.codingPath,
|
|
136
|
+
debugDescription: "Cannot get keyed decoding container -- found null value instead."
|
|
137
|
+
)
|
|
138
|
+
)
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
guard let array = value as? [Any] else {
|
|
142
|
+
let description = "Expected to decode \([Any].self) but found '\(value)' instead."
|
|
143
|
+
throw DecodingError.typeMismatch(
|
|
144
|
+
[Any].self,
|
|
145
|
+
DecodingError.Context(codingPath: self.codingPath, debugDescription: description)
|
|
146
|
+
)
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
self.currentIndex += 1
|
|
150
|
+
return RNUnkeyedDecodingContainer(referencing: self.decoder, wrapping: array)
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
func superDecoder() throws -> any Decoder {
|
|
154
|
+
self.decoder.codingPath.append(RNAnyCodingKey(intValue: self.currentIndex))
|
|
155
|
+
defer { self.decoder.codingPath.removeLast() }
|
|
156
|
+
|
|
157
|
+
guard !self.isAtEnd else {
|
|
158
|
+
throw DecodingError.valueNotFound(
|
|
159
|
+
Decoder.self,
|
|
160
|
+
DecodingError.Context(
|
|
161
|
+
codingPath: self.codingPath,
|
|
162
|
+
debugDescription: "Cannot get superDecoder() -- unkeyed container is at end."
|
|
163
|
+
)
|
|
164
|
+
)
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
let value = self.container[self.currentIndex]
|
|
168
|
+
self.currentIndex += 1
|
|
169
|
+
return RNInternalDecoder(
|
|
170
|
+
referencing: value,
|
|
171
|
+
at: self.decoder.codingPath,
|
|
172
|
+
userInfo: self.decoder.userInfo
|
|
173
|
+
)
|
|
174
|
+
}
|
|
175
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
struct RNAnyCodingKey: CodingKey, Equatable {
|
|
2
|
+
var stringValue: String
|
|
3
|
+
var intValue: Int?
|
|
4
|
+
|
|
5
|
+
init(stringValue: String) {
|
|
6
|
+
self.stringValue = stringValue
|
|
7
|
+
self.intValue = nil
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
init(intValue: Int) {
|
|
11
|
+
self.stringValue = "\(intValue)"
|
|
12
|
+
self.intValue = intValue
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
init<Key>(_ base: Key) where Key: CodingKey {
|
|
16
|
+
if let intValue = base.intValue {
|
|
17
|
+
self.init(intValue: intValue)
|
|
18
|
+
} else {
|
|
19
|
+
self.init(stringValue: base.stringValue)
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
extension RNAnyCodingKey: Hashable {
|
|
25
|
+
public func hash(into hasher: inout Hasher) {
|
|
26
|
+
if intValue != nil {
|
|
27
|
+
hasher.combine(intValue)
|
|
28
|
+
}
|
|
29
|
+
hasher.combine(stringValue)
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
|
|
3
|
+
public typealias CustomEncoder = (_ value: Encodable) throws -> Any?
|
|
4
|
+
public let customEncoderKey = CodingUserInfoKey(rawValue: "customEncoder")!
|
|
5
|
+
|
|
6
|
+
final public class RNEncoder {
|
|
7
|
+
public init() {}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
A dictionary you use to customize the encoding process
|
|
11
|
+
by providing contextual information.
|
|
12
|
+
*/
|
|
13
|
+
public var userInfo: [CodingUserInfoKey: Any] = [:]
|
|
14
|
+
|
|
15
|
+
public func encode<T>(_ value: T) throws -> Any where T: Encodable {
|
|
16
|
+
if let customEncoder = self.userInfo[customEncoderKey] {
|
|
17
|
+
if let result = try (customEncoder as! CustomEncoder)(value) {
|
|
18
|
+
return result
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let encoder = RNObjectEncoder(userInfo: self.userInfo)
|
|
23
|
+
try value.encode(to: encoder)
|
|
24
|
+
return encoder.data
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
// MARK: - TopLevelEncoder
|
|
29
|
+
|
|
30
|
+
#if canImport(Combine)
|
|
31
|
+
import Combine
|
|
32
|
+
|
|
33
|
+
extension RNEncoder: TopLevelEncoder {}
|
|
34
|
+
#endif
|
|
35
|
+
|
|
36
|
+
// MARK: -
|
|
37
|
+
|
|
38
|
+
protocol RNEncodingContainer {
|
|
39
|
+
var data: Any? { get }
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
class RNObjectEncoder {
|
|
43
|
+
var codingPath: [CodingKey] = []
|
|
44
|
+
|
|
45
|
+
var userInfo: [CodingUserInfoKey: Any] = [:]
|
|
46
|
+
|
|
47
|
+
fileprivate var container: RNEncodingContainer?
|
|
48
|
+
|
|
49
|
+
var data: Any {
|
|
50
|
+
return container?.data ?? NSDictionary()
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
init(userInfo: [CodingUserInfoKey: Any]) {
|
|
54
|
+
self.userInfo = userInfo
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
extension RNObjectEncoder: Encoder {
|
|
59
|
+
fileprivate func assertCanCreateContainer() {
|
|
60
|
+
precondition(self.container == nil)
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> where Key: CodingKey {
|
|
64
|
+
assertCanCreateContainer()
|
|
65
|
+
|
|
66
|
+
let container = RNKeyedEncodingContainer<Key>(
|
|
67
|
+
codingPath: self.codingPath,
|
|
68
|
+
userInfo: self.userInfo
|
|
69
|
+
)
|
|
70
|
+
self.container = container
|
|
71
|
+
|
|
72
|
+
return KeyedEncodingContainer(container)
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
|
76
|
+
assertCanCreateContainer()
|
|
77
|
+
|
|
78
|
+
let container = RNUnkeyedEncodingContainer(codingPath: self.codingPath, userInfo: self.userInfo)
|
|
79
|
+
self.container = container
|
|
80
|
+
|
|
81
|
+
return container
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
func singleValueContainer() -> SingleValueEncodingContainer {
|
|
85
|
+
assertCanCreateContainer()
|
|
86
|
+
|
|
87
|
+
let container = RNSingleValueEncodingContainer(
|
|
88
|
+
codingPath: self.codingPath,
|
|
89
|
+
userInfo: self.userInfo
|
|
90
|
+
)
|
|
91
|
+
self.container = container
|
|
92
|
+
|
|
93
|
+
return container
|
|
94
|
+
}
|
|
95
|
+
}
|