Skip to content

Commit d9b79cc

Browse files
committed
[Distributed] remoteCall decoding without foundation
1 parent 42108f3 commit d9b79cc

File tree

2 files changed

+394
-25
lines changed

2 files changed

+394
-25
lines changed
Lines changed: 369 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,369 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the Swift open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
/// Fake encoder intended to serialize into a string representation easy to
16+
/// assert on.
17+
public final class FakeEncoder {
18+
public func encode<T: Encodable>(_ value: T) throws -> String {
19+
let stringsEncoding = StringsEncoding()
20+
try value.encode(to: stringsEncoding)
21+
return dotStringsFormat(from: stringsEncoding.data.strings)
22+
}
23+
24+
private func dotStringsFormat(from strings: [String: String]) -> String {
25+
var dotStrings = strings.map { k, v -> String in
26+
if k.isEmpty {
27+
return "\(v);"
28+
} else {
29+
return "\(k): \(v);"
30+
}
31+
}
32+
return dotStrings.joined(separator: " ")
33+
}
34+
}
35+
36+
fileprivate struct StringsEncoding: Encoder {
37+
fileprivate final class Storage {
38+
private(set) var strings: [String: String] = [:]
39+
40+
func encode(key codingKey: [CodingKey], value: String) {
41+
let key = codingKey.map { $0.stringValue }
42+
.joined(separator: ".")
43+
strings[key] = value
44+
}
45+
}
46+
47+
fileprivate var data: Storage
48+
49+
init(to encoded: Storage = Storage()) {
50+
self.data = encoded
51+
}
52+
53+
var codingPath: [CodingKey] = []
54+
55+
let userInfo: [CodingUserInfoKey: Any] = [:]
56+
57+
func container<Key: CodingKey>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> {
58+
var container = StringsKeyedEncoding<Key>(to: data)
59+
container.codingPath = codingPath
60+
return KeyedEncodingContainer(container)
61+
}
62+
63+
func unkeyedContainer() -> UnkeyedEncodingContainer {
64+
var container = StringsUnkeyedEncoding(to: data)
65+
container.codingPath = codingPath
66+
return container
67+
}
68+
69+
func singleValueContainer() -> SingleValueEncodingContainer {
70+
var container = StringsSingleValueEncoding(to: data)
71+
container.codingPath = codingPath
72+
return container
73+
}
74+
}
75+
76+
fileprivate struct StringsKeyedEncoding<Key: CodingKey>: KeyedEncodingContainerProtocol {
77+
78+
private let data: StringsEncoding.Storage
79+
80+
init(to data: StringsEncoding.Storage) {
81+
self.data = data
82+
}
83+
84+
var codingPath: [CodingKey] = []
85+
86+
mutating func encodeNil(forKey key: Key) throws {
87+
data.encode(key: codingPath + [key], value: "nil")
88+
}
89+
90+
mutating func encode(_ value: Bool, forKey key: Key) throws {
91+
data.encode(key: codingPath + [key], value: value.description)
92+
}
93+
94+
mutating func encode(_ value: String, forKey key: Key) throws {
95+
data.encode(key: codingPath + [key], value: value)
96+
}
97+
98+
mutating func encode(_ value: Double, forKey key: Key) throws {
99+
data.encode(key: codingPath + [key], value: value.description)
100+
}
101+
102+
mutating func encode(_ value: Float, forKey key: Key) throws {
103+
data.encode(key: codingPath + [key], value: value.description)
104+
}
105+
106+
mutating func encode(_ value: Int, forKey key: Key) throws {
107+
data.encode(key: codingPath + [key], value: value.description)
108+
}
109+
110+
mutating func encode(_ value: Int8, forKey key: Key) throws {
111+
data.encode(key: codingPath + [key], value: value.description)
112+
}
113+
114+
mutating func encode(_ value: Int16, forKey key: Key) throws {
115+
data.encode(key: codingPath + [key], value: value.description)
116+
}
117+
118+
mutating func encode(_ value: Int32, forKey key: Key) throws {
119+
data.encode(key: codingPath + [key], value: value.description)
120+
}
121+
122+
mutating func encode(_ value: Int64, forKey key: Key) throws {
123+
data.encode(key: codingPath + [key], value: value.description)
124+
}
125+
126+
mutating func encode(_ value: UInt, forKey key: Key) throws {
127+
data.encode(key: codingPath + [key], value: value.description)
128+
}
129+
130+
mutating func encode(_ value: UInt8, forKey key: Key) throws {
131+
data.encode(key: codingPath + [key], value: value.description)
132+
}
133+
134+
mutating func encode(_ value: UInt16, forKey key: Key) throws {
135+
data.encode(key: codingPath + [key], value: value.description)
136+
}
137+
138+
mutating func encode(_ value: UInt32, forKey key: Key) throws {
139+
data.encode(key: codingPath + [key], value: value.description)
140+
}
141+
142+
mutating func encode(_ value: UInt64, forKey key: Key) throws {
143+
data.encode(key: codingPath + [key], value: value.description)
144+
}
145+
146+
mutating func encode<T: Encodable>(_ value: T, forKey key: Key) throws {
147+
var stringsEncoding = StringsEncoding(to: data)
148+
stringsEncoding.codingPath.append(key)
149+
try value.encode(to: stringsEncoding)
150+
}
151+
152+
mutating func nestedContainer<NestedKey: CodingKey>(
153+
keyedBy keyType: NestedKey.Type,
154+
forKey key: Key) -> KeyedEncodingContainer<NestedKey> {
155+
var container = StringsKeyedEncoding<NestedKey>(to: data)
156+
container.codingPath = codingPath + [key]
157+
return KeyedEncodingContainer(container)
158+
}
159+
160+
mutating func nestedUnkeyedContainer(forKey key: Key) -> UnkeyedEncodingContainer {
161+
var container = StringsUnkeyedEncoding(to: data)
162+
container.codingPath = codingPath + [key]
163+
return container
164+
}
165+
166+
mutating func superEncoder() -> Encoder {
167+
let superKey = Key(stringValue: "super")!
168+
return superEncoder(forKey: superKey)
169+
}
170+
171+
mutating func superEncoder(forKey key: Key) -> Encoder {
172+
var stringsEncoding = StringsEncoding(to: data)
173+
stringsEncoding.codingPath = codingPath + [key]
174+
return stringsEncoding
175+
}
176+
}
177+
178+
fileprivate struct StringsUnkeyedEncoding: UnkeyedEncodingContainer {
179+
private let data: StringsEncoding.Storage
180+
181+
init(to data: StringsEncoding.Storage) {
182+
self.data = data
183+
}
184+
185+
var codingPath: [CodingKey] = []
186+
private(set) var count: Int = 0
187+
188+
private mutating func nextIndexedKey() -> CodingKey {
189+
let nextCodingKey = IndexedCodingKey(intValue: count)!
190+
count += 1
191+
return nextCodingKey
192+
}
193+
194+
private struct IndexedCodingKey: CodingKey {
195+
let intValue: Int?
196+
let stringValue: String
197+
198+
init?(intValue: Int) {
199+
self.intValue = intValue
200+
self.stringValue = intValue.description
201+
}
202+
203+
init?(stringValue: String) {
204+
return nil
205+
}
206+
}
207+
208+
mutating func encodeNil() throws {
209+
data.encode(key: codingPath + [nextIndexedKey()], value: "nil")
210+
}
211+
212+
mutating func encode(_ value: Bool) throws {
213+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
214+
}
215+
216+
mutating func encode(_ value: String) throws {
217+
data.encode(key: codingPath + [nextIndexedKey()], value: value)
218+
}
219+
220+
mutating func encode(_ value: Double) throws {
221+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
222+
}
223+
224+
mutating func encode(_ value: Float) throws {
225+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
226+
}
227+
228+
mutating func encode(_ value: Int) throws {
229+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
230+
}
231+
232+
mutating func encode(_ value: Int8) throws {
233+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
234+
}
235+
236+
mutating func encode(_ value: Int16) throws {
237+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
238+
}
239+
240+
mutating func encode(_ value: Int32) throws {
241+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
242+
}
243+
244+
mutating func encode(_ value: Int64) throws {
245+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
246+
}
247+
248+
mutating func encode(_ value: UInt) throws {
249+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
250+
}
251+
252+
mutating func encode(_ value: UInt8) throws {
253+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
254+
}
255+
256+
mutating func encode(_ value: UInt16) throws {
257+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
258+
}
259+
260+
mutating func encode(_ value: UInt32) throws {
261+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
262+
}
263+
264+
mutating func encode(_ value: UInt64) throws {
265+
data.encode(key: codingPath + [nextIndexedKey()], value: value.description)
266+
}
267+
268+
mutating func encode<T: Encodable>(_ value: T) throws {
269+
var stringsEncoding = StringsEncoding(to: data)
270+
stringsEncoding.codingPath = codingPath + [nextIndexedKey()]
271+
try value.encode(to: stringsEncoding)
272+
}
273+
274+
mutating func nestedContainer<NestedKey: CodingKey>(
275+
keyedBy keyType: NestedKey.Type) -> KeyedEncodingContainer<NestedKey> {
276+
var container = StringsKeyedEncoding<NestedKey>(to: data)
277+
container.codingPath = codingPath + [nextIndexedKey()]
278+
return KeyedEncodingContainer(container)
279+
}
280+
281+
mutating func nestedUnkeyedContainer() -> UnkeyedEncodingContainer {
282+
var container = StringsUnkeyedEncoding(to: data)
283+
container.codingPath = codingPath + [nextIndexedKey()]
284+
return container
285+
}
286+
287+
mutating func superEncoder() -> Encoder {
288+
var stringsEncoding = StringsEncoding(to: data)
289+
stringsEncoding.codingPath.append(nextIndexedKey())
290+
return stringsEncoding
291+
}
292+
}
293+
294+
fileprivate struct StringsSingleValueEncoding: SingleValueEncodingContainer {
295+
296+
private let data: StringsEncoding.Storage
297+
298+
init(to data: StringsEncoding.Storage) {
299+
self.data = data
300+
}
301+
302+
var codingPath: [CodingKey] = []
303+
304+
mutating func encodeNil() throws {
305+
data.encode(key: codingPath, value: "nil")
306+
}
307+
308+
mutating func encode(_ value: Bool) throws {
309+
data.encode(key: codingPath, value: value.description)
310+
}
311+
312+
mutating func encode(_ value: String) throws {
313+
data.encode(key: codingPath, value: value)
314+
}
315+
316+
mutating func encode(_ value: Double) throws {
317+
data.encode(key: codingPath, value: value.description)
318+
}
319+
320+
mutating func encode(_ value: Float) throws {
321+
data.encode(key: codingPath, value: value.description)
322+
}
323+
324+
mutating func encode(_ value: Int) throws {
325+
data.encode(key: codingPath, value: value.description)
326+
}
327+
328+
mutating func encode(_ value: Int8) throws {
329+
data.encode(key: codingPath, value: value.description)
330+
}
331+
332+
mutating func encode(_ value: Int16) throws {
333+
data.encode(key: codingPath, value: value.description)
334+
}
335+
336+
mutating func encode(_ value: Int32) throws {
337+
data.encode(key: codingPath, value: value.description)
338+
}
339+
340+
mutating func encode(_ value: Int64) throws {
341+
data.encode(key: codingPath, value: value.description)
342+
}
343+
344+
mutating func encode(_ value: UInt) throws {
345+
data.encode(key: codingPath, value: value.description)
346+
}
347+
348+
mutating func encode(_ value: UInt8) throws {
349+
data.encode(key: codingPath, value: value.description)
350+
}
351+
352+
mutating func encode(_ value: UInt16) throws {
353+
data.encode(key: codingPath, value: value.description)
354+
}
355+
356+
mutating func encode(_ value: UInt32) throws {
357+
data.encode(key: codingPath, value: value.description)
358+
}
359+
360+
mutating func encode(_ value: UInt64) throws {
361+
data.encode(key: codingPath, value: value.description)
362+
}
363+
364+
mutating func encode<T: Encodable>(_ value: T) throws {
365+
var stringsEncoding = StringsEncoding(to: data)
366+
stringsEncoding.codingPath = codingPath
367+
try value.encode(to: stringsEncoding)
368+
}
369+
}

0 commit comments

Comments
 (0)