File: Serialization.swift

package info (click to toggle)
swiftlang 6.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856,264 kB
  • sloc: cpp: 9,995,718; ansic: 2,234,019; asm: 1,092,167; python: 313,940; objc: 82,726; f90: 80,126; lisp: 38,373; pascal: 25,580; sh: 20,378; ml: 5,058; perl: 4,751; makefile: 4,725; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (1024 lines) | stat: -rw-r--r-- 41,495 bytes parent folder | download
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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
//===----------------------------------------------------------------------===//
//
// This source file is part of the Swift open source project
//
// Copyright (c) 2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

public import class Foundation.JSONDecoder
public import class Foundation.JSONEncoder
public import struct Foundation.Data
public import struct Foundation.Date
public import protocol Foundation.LocalizedError

// MARK: Serializer and Deserializer protocols


/// A `Serializer` is used to create a serialized `ByteString` representation of a collection of objects or other data, suitable for writing as a single file or otherwise transporting as a single piece of data.  Classes or structs to be serialized by adopt either the `Serializable` or `PolymorphicSerializable` protocols.  Many common built-in types already adopt `Serializable` through extensions.
///
/// An element is serialized by invoking the serializer like so:
///
///     serializer.serialize(element)
///
/// For custom elements such as classes which have multiple elements, serialization of the elements should be bracketed by `beginAggregate()` and `endAggregate()` calls, with the former containing the number of elements.  For example:
///
///     serializer.beginAggregate(3)
///     serializer.serialize(firstElement)
///     serializer.serialize(secondElement)
///     serializer.serialize(thirdElement)
///     serializer.endAggregate()
///
/// For class hierarchies, each subclass should invoke `super.serialize(to:)` as defined in the `Serializable` protocol, and the super invocation should be treated as a separate element (which itself should bracket its elements with `beginAggregate()` and `endAggregate()`), for example:
///
///     serializer.beginAggregate(3)
///     serializer.serialize(firstElement)
///     serializer.serialize(secondElement)
///     super.serialize(to: serializer)
///     serializer.endAggregate()
///
/// A `Serializer` can be instantiated with a `SerializerDelegate` object to provide custom behavior or record information during serialization.
public protocol Serializer
{
    init(delegate: (any SerializerDelegate)?)

    /// The `ByteString` containing the serialized data.
    var byteString: ByteString { get }

    var delegate: (any SerializerDelegate)? { get }

    /// Serialize an `Int`.
    func serialize(_ int: Int)

    /// Serialize a `UInt`.
    func serialize(_ uint: UInt)

    /// Serialize a `UInt8`.
    func serialize(_ byte: UInt8)

    /// Serialize a `Bool`.
    func serialize(_ bool: Bool)

    /// Serialize a `Float32`.
    func serialize(_ float: Float32)

    /// Serialize a `Float64`.
    func serialize(_ float: Float64)

    /// Serialize a `String`.
    func serialize(_ string: String)

    // Serialize an array of bytes.
    func serialize(_ bytes: [UInt8])

    // Serialize a date.
    func serialize(_ date: Date)

    /// Serialize a `Serializable` scalar element.
    func serialize<T: Serializable>(_ object: T)

    /// Serialize an `Array` whose elements are `Serializable`.
    func serialize<T: Serializable>(_ array: [T])

    /// Serialize a `Dictionary` whose keys and values are `Serializable`.
    func serialize<Tk: Serializable & Comparable, Tv: Serializable>(_ dict: [Tk: Tv])

    func serialize<Tk: Serializable & Comparable, Tv: Serializable>(_ dict: [Tk: [Tv]])

    func serialize<Tk: Serializable & Comparable, Tv: Serializable>(_ dict: [Tk?: [Tv]])

    /// Serialize `nil`.
    func serializeNil()

    /// Begin serializing an aggregate element as an array scalar, by noting the number of individual elements that make up the aggregate element.
    func beginAggregate(_ count: Int)

    /// End serializing an aggregate element as an array scalar.
    func endAggregate()
}

public extension Serializer
{
    /// Convenience function for serializing a single value to bytes.
    static func serialize<T: Serializable>(_ value: T, delegate: (any SerializerDelegate)? = nil) -> ByteString
    {
        let serializer = Self.init(delegate: delegate)
        value.serialize(to: serializer)
        return serializer.byteString
    }

    /// Serialize an optional `Serializable` scalar element.
    func serialize<T: Serializable>(_ optional: T?)
    {
        guard let element = optional else { self.serializeNil(); return }
        self.serialize(element)
    }

    /// Serialize an optional array of bytes.
    func serialize(_ optional: [UInt8]?)
    {
        guard let element = optional else { self.serializeNil(); return }
        self.serialize(element)
    }

    // Serialize a date.
    func serialize(_ date: Date)
    {
        self.serialize(date.timeIntervalSinceReferenceDate)
    }

    /// Serialize an optional `Array` whose elements are `Serializable`.
    func serialize<T: Serializable>(_ optional: [T]?)
    {
        guard let array = optional else { self.serializeNil(); return }
        self.serialize(array)
    }

    func serialize<T: Serializable>(_ array: [[T]])
    {
        self.serializeAggregate(2) {
            self.serialize(array.count as Int)
            self.serializeAggregate(array.count) {
                for x in array {
                    self.serialize(x)
                }
            }
        }
    }

    /// Serialize an optional `Dictionary` whose keys and values are `Serializable`.
    func serialize<Tk: Serializable & Comparable, Tv: Serializable>(_ optional: [Tk: Tv]?)
    {
        guard let dict = optional else { self.serializeNil(); return }
        self.serialize(dict)
    }

    /// Serialize a `PolymorphicSerializable` element.
    func serialize<T: PolymorphicSerializable>(_ object: T)
    {
        let wrappedElement = PolymorphicSerializableWrapper<T>(object)
        self.serialize(wrappedElement)
    }

    /// Serialize an `Array` whose elements are `PolymorphicSerializable`.
    func serialize<T: PolymorphicSerializable>(_ array: [T])
    {
        let wrappedElements = array.map { PolymorphicSerializableWrapper<T>($0) }
        self.serialize(wrappedElements)
    }

    /// Serialize a `Dictionary` whose keys are `Serializable` and whose values are `PolymorphicSerializable`.
    func serialize<Tk: Serializable & Comparable, Tv: PolymorphicSerializable>(_ dict: [Tk: Tv])
    {
        var wrappedDict = [Tk: PolymorphicSerializableWrapper<Tv>](minimumCapacity: dict.count)
        for (key, value) in dict.sorted(byKey: <)
        {
            wrappedDict[key] = PolymorphicSerializableWrapper<Tv>(value)
        }
        self.serialize(wrappedDict)
    }

    /// Serialize a `Dictionary` whose keys are `PolymorphicSerializable` and whose values are `Serializable`.
    func serialize<Tk: PolymorphicSerializable & Comparable, Tv: Serializable>(_ dict: [Tk: Tv])
    {
        // In order to do this, we serialize the dictionary as a sequence of key-value pairs, so that we don't need to make PolymorphicSerializableWrapper<Tk> conform to Hashable and Equatable.
        self.beginAggregate(dict.count)
        for (key, value) in dict.sorted(byKey: <)
        {
            // Each pair is encoded as a 2-element sequence.
            self.beginAggregate(2)
            self.serialize(key)
            self.serialize(value)
            self.endAggregate()
        }
        self.endAggregate()
    }

    /// Serialize a `Dictionary` whose keys and values are `PolymorphicSerializable`.
    func serialize<Tk: PolymorphicSerializable & Comparable, Tv: PolymorphicSerializable>(_ dict: [Tk: Tv])
    {
        // In order to do this, we serialize the dictionary as a sequence of key-value pairs, so that we don't need to make PolymorphicSerializableWrapper<Tk> conform to Hashable and Equatable.
        self.beginAggregate(dict.count)
        for (key, value) in dict.sorted(byKey: <)
        {
            // Each pair is encoded as a 2-element sequence.
            self.beginAggregate(2)
            self.serialize(key)
            self.serialize(value)
            self.endAggregate()
        }
        self.endAggregate()
    }

    /// Serialize an optional `PolymorphicSerializable` element.
    func serialize<T: PolymorphicSerializable>(_ optional: T?)
    {
        guard let element = optional else { self.serializeNil(); return }
        self.serialize(element)
    }

    /// Serialize an optional `Array` whose elements are `PolymorphicSerializable`.
    func serialize<T: PolymorphicSerializable>(_ optional: [T]?)
    {
        guard let array = optional else { self.serializeNil(); return }
        self.serialize(array)
    }

    /// Serialize an optional `Dictionary` whose keys are `Serializable` and whose values are `PolymorphicSerializable`.
    func serialize<Tk: Serializable & Comparable, Tv: PolymorphicSerializable>(_ optional: [Tk: Tv]?)
    {
        guard let dict = optional else { self.serializeNil(); return }
        self.serialize(dict)
    }


    /// Serialize an optional `Dictionary` whose keys are `PolymorphicSerializable` and whose values are `Serializable`.
    func serialize<Tk: PolymorphicSerializable & Comparable, Tv: Serializable>(_ optional: [Tk: Tv]?)
    {
        guard let dict = optional else { self.serializeNil(); return }
        self.serialize(dict)
    }

    /// Serialize an optional `Dictionary` whose keys and values are `PolymorphicSerializable`.
    func serialize<Tk: PolymorphicSerializable & Comparable, Tv: PolymorphicSerializable>(_ optional: [Tk: Tv]?)
    {
        guard let dict = optional else { self.serializeNil(); return }
        self.serialize(dict)
    }

    func serialize<T: Serializable>(_ range: Range<T>) {
        self.serializeAggregate(2) {
            self.serialize(range.lowerBound)
            self.serialize(range.upperBound)
        }
    }

    /// Shorthand for { beginAggregate(count); f(); endAggregate() }
    func serializeAggregate(_ count: Int, _ f: () -> Void) {
        self.beginAggregate(count)
        f()
        self.endAggregate()
    }
}

/// Protocol for a delegate to be used by an instance of a `Serializer`.
///
/// Such a delegate will typically be used to record information during the course of serializing an object graph to to be used later in the serialization process.  For example, to associate identifiers with a number of serialized objects so that later serializations of those objects can serialize the identifiers as references to the objects rather than serializing the objects multiple times.
///
/// Typically an object's `serialize(to:)` method will retrieve the delegate like this:
///
///     guard var delegate = serializer.delegate as? ConcreteSerializerDelegate else { fatalError("delegate must be a ConcreteSerializerDelegate") }
///
/// `let` may be used instead of `var` if the object is not modifying the content of the delegate.
public protocol SerializerDelegate: AnyObject
{
}


/// A `Deserializer` is used to unpack a serialized `ByteString` representation of a collection of objects or other data which was serialized with a corresponding `Serializer`.
///
/// An element is deserialized by invoking the deserializer in a context where the type to be deserializer can be inferred by the compiler, like so:
///
///     self.element = try deserializer.deserialize()
///
/// The deserializer will throw a `DeserializerError` if an error is encountered during deserialization.
///
/// For custom elements such as classes which have multiple elements, deserialization should be preceded by a call to `beginAggregate()` with the expected number of elements to be deserialized, for example:
///
///     try deserializer.beginAggregate(3)
///     self.firstElement = try deserializer.deserialize()
///     self.secondElement = try deserializer.deserialize()
///     self.thirdElement = try deserializer.deserialize()
///
/// Unlike serialization, no corresponding `endAggregate()` call is needed.
///
/// Alternately, `beginAggregate()` can be called without a parameter, and it will return the number of elements to be deserialized.  This is useful when deserializing a variable-count aggregate, such as an array of elements.
///
/// For class hierarchies, each subclass should invoke `super.init(from:)` as defined in the `Serializable` protocol, and the super invocation should be treated as a separate element (which itself should start with a call to `beginAggregate()`), for example:
///
///     try deserializer.beginAggregate(3)
///     self.firstElement = try deserializer.deserialize()
///     self.secondElement = try deserializer.deserialize()
///     try super.init(from: deserializer)
///
/// A `Deserializer` can be instantiated with a `DeserializerDelegate` object to provide custom behavior or record information during deserialization.
public protocol Deserializer
{
    init(_ bytes: ArraySlice<UInt8>, delegate: (any DeserializerDelegate)?)

    var delegate: (any DeserializerDelegate)? { get }

    /// Deserialize an `Int`.  Throws if the next item to be deserialized is not an `Int`.
    func deserialize() throws -> Int

    /// Deserialize a `UInt`.  Throws if the next item to be deserialized is not a `UInt`.
    func deserialize() throws -> UInt

    /// Deserialize a `UInt8`.  Throws if the next item to be deserialized is not a `UInt8`.
    func deserialize() throws -> UInt8

    /// Deserialize a `Bool`.  Throws if the next item to be deserialized is not a `Bool`.
    func deserialize() throws -> Bool

    /// Deserialize a `Float32`.  Throws if the next item to be deserialized is not a `Float32`.
    func deserialize() throws -> Float32

    /// Deserialize a `Float64`.  Throws if the next item to be deserialized is not a `Float64`.
    func deserialize() throws -> Float64

    /// Deserialize a `String`.  Throws if the next item to be deserialized is not a `String`.
    func deserialize() throws -> String

    /// Deserialize an array of bytes.  Throws if the next item to be deserialized is not such an array.
    func deserialize() throws -> [UInt8]

    /// Deserialize a date.  Throws if the next item to be deserialized is not such a date.
    func deserialize() throws -> Date

    /// Deserialize a `Serializable` scalar element.
    func deserialize<T: Serializable>() throws -> T

    /// Deserialize an `Array`.  Throws if the next item to be deserialized is not an `Array`, or if the array could not be read.
    func deserialize<T: Serializable>() throws -> [T]

    /// Deserialize a `Dictionary` whose keys and values are `Serializable`.  Throws if the next item to be deserialized is not a `Dictionary`, or if the dictionary could not be read.
    func deserialize<Tk: Serializable, Tv: Serializable>() throws -> [Tk: Tv]

    func deserialize<Tk: Serializable, Tv: Serializable>() throws -> [Tk: [Tv]]

    func deserialize<Tk: Serializable, Tv: Serializable>() throws -> [Tk?: [Tv]]

    /// Deserialize `nil`.  Returns `true` if nil was deserialized.  If `nil` could not be deserialized, then returns `false` and does not consume any data from the byte string.
    func deserializeNil() -> Bool

    /// Begin deserializing an aggregate element.  Throws if the next item to be deserialized is not an aggregate.
    /// - parameter expectedCount: Throws if the number of elements to be deserialized is not in this range.
    ///
    /// This can be used to more conveniently let a `Serializable` type handle older versions with different numbers of fields,
    /// by taking different branches depending on the number of fields present in the serialized data.
    func beginAggregate(_ range: CountableClosedRange<Int>) throws -> Int

    /// Begin deserializing an aggregate element.  Throws if the next item to be deserialized is not an aggregate.
    /// - parameter expectedCount: Throws if the number of elements to be deserialized is not this number.
    func beginAggregate(_ expectedCount: Int) throws

    /// Begin deserializing an aggregate element.  Throws if the next item to be deserialized is not an aggregate.
    /// - returns: The count of elements serialized.
    func beginAggregate() throws -> Int
}


public extension Deserializer
{
    /// Convenience function for serializing a single value from bytes.
    static func deserialize<T: Serializable>(_ bytes: ByteString, delegate: (any DeserializerDelegate)? = nil) throws -> T
    {
        let deserializer = Self.init(bytes, delegate: delegate)
        return try deserializer.deserialize()
    }

    init(_ byteString: ByteString, delegate: (any DeserializerDelegate)? = nil)
    {
        self.init(ArraySlice(byteString.bytes), delegate: delegate)
    }

    /// Deserialize an optional `Serializable` scalar element.
    func deserialize<T: Serializable>() throws -> T?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as T)
    }

    /// Deserialize an optional array of bytes.
    func deserialize() throws -> [UInt8]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [UInt8])
    }

    /// Deserialize a date.
    func deserialize() throws -> Date
    {
        return try Date(timeIntervalSinceReferenceDate: self.deserialize())
    }

    /// Deserialize an optional `Array`.  Throws if the next item to be deserialized is not nil or an `Array`, or if the array could not be read.
    func deserialize<T: Serializable>() throws -> [T]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [T])
    }

    func deserialize<T: Serializable>() throws -> [[T]]
    {
        try beginAggregate(2)
        let count = try deserialize() as Int
        guard count >= 0 else { throw DeserializerError.unexpectedValue("Expected array count >= 0") }

        try beginAggregate(count)
        var result = [[T]]()
        result.reserveCapacity(count)

        for _ in 0 ..< count {
            result.append(try deserialize())
        }

        return result
    }

    /// Deserialize an optional `Dictionary` whose keys and values are `Serializable`.  Throws if the next item to be deserialized is not nil or a `Dictionary`, or if the dictionary could not be read.
    func deserialize<Tk: Serializable, Tv: Serializable>() throws -> [Tk: Tv]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [Tk: Tv])
    }

    /// Deserialize a `PolymorphicSerializable` element.
    func deserialize<T: PolymorphicSerializable>() throws -> T
    {
        let wrappedElement: PolymorphicSerializableWrapper<T> = try self.deserialize()
        return wrappedElement.value
    }

    /// Deserialize an `Array` whose elements are `PolymorphicSerializable`.
    func deserialize<T: PolymorphicSerializable>() throws -> [T]
    {
        let wrappedElements: [PolymorphicSerializableWrapper<T>] = try self.deserialize()
        return wrappedElements.map { $0.value }
    }

    /// Deserialize a `Dictionary` whose keys are `Serializable` and whose values are `PolymorphicSerializable`.
    func deserialize<Tk: Serializable, Tv: PolymorphicSerializable>() throws -> [Tk: Tv]
    {
        let wrappedDict: [Tk: PolymorphicSerializableWrapper<Tv>] = try self.deserialize()
        var dict = [Tk: Tv](minimumCapacity: wrappedDict.count)
        for (key, wrappedValue) in wrappedDict
        {
            dict[key] = wrappedValue.value
        }
        return dict
    }

    /// Deserialize a `Dictionary` whose keys are `PolymorphicSerializable` and whose values are `Serializable`.
    func deserialize<Tk: PolymorphicSerializable, Tv: Serializable>() throws -> [Tk: Tv]
    {
        // The dictionary is serialized as a sequence of key-value pairs.
        let count = try self.beginAggregate()
        guard count > 0 else { return [:] }
        var dict = [Tk: Tv](minimumCapacity: count)
        for _ in 1...count
        {
            // Each pair is encoded as a 2-element sequence.
            try self.beginAggregate(2)
            let key: PolymorphicSerializableWrapper<Tk> = try self.deserialize()
            let value: Tv = try self.deserialize()
            dict[key.value] = value
        }
        return dict
    }

    /// Deserialize a `Dictionary` whose keys and values are `PolymorphicSerializable`.
    func deserialize<Tk: PolymorphicSerializable, Tv: PolymorphicSerializable>() throws -> [Tk: Tv]
    {
        // The dictionary is serialized as a sequence of key-value pairs.
        let count = try self.beginAggregate()
        guard count > 0 else { return [:] }
        var dict = [Tk: Tv](minimumCapacity: count)
        for _ in 1...count
        {
            // Each pair is encoded as a 2-element sequence.
            try self.beginAggregate(2)
            let key: PolymorphicSerializableWrapper<Tk> = try self.deserialize()
            let value: Tv = try self.deserialize()
            dict[key.value] = value
        }
        return dict
    }

    /// Deserialize an optional `PolymorphicSerializable` element.
    func deserialize<T: PolymorphicSerializable>() throws -> T?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as T)
    }

    /// Deserialize an optional `Array` whose elements are `PolymorphicSerializable`.
    func deserialize<T: PolymorphicSerializable>() throws -> [T]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [T])
    }

    /// Deserialize an optional `Dictionary` whose keys are `Serializable` and whose values are `PolymorphicSerializable`.
    func deserialize<Tk: Serializable, Tv: PolymorphicSerializable>() throws -> [Tk: Tv]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [Tk: Tv])
    }

    /// Deserialize an optional `Dictionary` whose keys are `PolymorphicSerializable` and whose values are `Serializable`.
    func deserialize<Tk: PolymorphicSerializable, Tv: Serializable>() throws -> [Tk: Tv]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [Tk: Tv])
    }

    /// Deserialize an optional `Dictionary` whose keys and values are `PolymorphicSerializable`.
    func deserialize<Tk: PolymorphicSerializable, Tv: PolymorphicSerializable>() throws -> [Tk: Tv]?
    {
        return self.deserializeNil() ? nil : (try self.deserialize() as [Tk: Tv])
    }

    func deserialize<T: Serializable>() throws -> Range<T> {
        try self.beginAggregate(2)
        let lower: T = try self.deserialize()
        let upper: T = try self.deserialize()
        return Range(uncheckedBounds: (lower: lower, upper: upper))
    }

    /// Deserializes `nil` and throws DeserializerError.incorrectType if it fails.
    func deserializeNilThrow() throws {
        if !self.deserializeNil() {
            throw DeserializerError.incorrectType("expected nil")
        }
    }
}


/// Protocol for a delegate to be used by an instance of a `Deserializer`.
///
/// Such a delegate typically has two purposes:
///
/// 1. For the creator of the `Deserializer` to provide context objects to be used during deserialization.  For example, to look up objects using identifiers being deserialized in a context outside of the deserializer.
/// 2. To to record information during the course of deserializing an object graph to to be used later in the deserialization process.  For example, to associate identifiers with a number of serialized objects so that when those identifiers are encountered later in deserialization, the previously-deserialized objects can be re-used rather than creating new ones.  If the delegate is used for this purpose, then it should be a class and not a struct.
///
/// Typically an object's `init(from:)` method will retrieve the delegate like this:
///
///     guard var delegate = deserializer.delegate as? ConcreteDeserializerDelegate else { throw DeserializerError.invalidDelegate("delegate must be a ConcreteDeserializerDelegate") }
///
/// `let` may be used instead of `var` if the object is not modifying the content of the delegate.
public protocol DeserializerDelegate
{
}


public enum DeserializerError: Swift.Error, LocalizedError, CustomStringConvertible
{
    /// A class' `init(from:)` method can throw this error if it does not get the type of `DeserializerDelegate` it expects.
    case invalidDelegate(String)
    /// This error is thrown if the type of the next item to be deserialized is not of the expected type.
    case incorrectType(String)
    /// This error is thrown if a value used in the encoding was unexpected (for example, an known type code).
    case unexpectedValue(String)
    /// This error is thrown if deserialization of one or more elements failed.
    case deserializationFailed(String)

    public var description: String {
        switch self {
        case .invalidDelegate(let str):
            return "Invalid deserializer delegate: \(str)"
        case .incorrectType(let str):
            return "Deserialized incorrect type: \(str)"
        case .unexpectedValue(let str):
            return "Deserialized unexpected value: \(str)"
        case .deserializationFailed(let str):
            return "Deserialization failed: \(str)"
        }
    }

    public var errorDescription: String? { description }

    public var errorString: String
    {
        switch self
        {
            case .invalidDelegate(let str): return str
            case .incorrectType(let str): return str
            case .unexpectedValue(let str): return str
            case .deserializationFailed(let str): return str
        }
    }
}


// MARK: Serializable protocol


/// Protocol for simple types which can be serialized.
///
/// Class hierarchies should adopt `PolymorphicSerializable` instead.
public protocol Serializable
{
    /// Serialize the receiver.
    func serialize<T: Serializer>(to serializer: T)

    /// Create a new instance of the receiver from a deserializer.
    init(from deserializer: any Deserializer) throws
}

private enum LegacyDecodingError: Error {
    case legacyDecodingNotImplemented
}

public protocol SerializableCodable: Serializable, Codable {
    init(fromLegacy deserializer: any Deserializer) throws
}

extension SerializableCodable {
    public func serialize<T>(to serializer: T) where T : Serializer {
        try! serializer.serialize(Array(JSONEncoder(outputFormatting: [.sortedKeys, .withoutEscapingSlashes]).encode(self)))
    }

    public init(from deserializer: any Deserializer) throws {
        let data: Data
        do {
            data = try Data(deserializer.deserialize())
        } catch let newError {
            do {
                self = try .init(fromLegacy: deserializer)
                return
            } catch LegacyDecodingError.legacyDecodingNotImplemented {
                // If we didn't implement legacy decoding for this type, throw the original error from the new decoder
                throw newError
            }
        }

        self = try JSONDecoder().decode(Self.self, from: data)
    }

    public init(fromLegacy deserializer: any Deserializer) throws {
        throw LegacyDecodingError.legacyDecodingNotImplemented
    }
}

/// May be used to migrate a Serializable type to SerializableCodable without requiring an updated client immediately. Types conforming to this protocol will still use legacy serialization, but support legacy or codable deserialization. Once client versions in use all support deserializing the codable representation, these types can switch to `SerializableCodable`.
public protocol PendingSerializableCodable: Serializable, Codable {
    func legacySerialize<T>(to serializer: T) where T : Serializer
    init(fromLegacy deserializer: any Deserializer) throws
}

extension PendingSerializableCodable {
    public func serialize<T>(to serializer: T) where T : Serializer {
        legacySerialize(to: serializer)
    }

    public init(from deserializer: any Deserializer) throws {
        let data: Data
        do {
            data = try Data(deserializer.deserialize())
        } catch let newError {
            do {
                self = try .init(fromLegacy: deserializer)
                return
            } catch LegacyDecodingError.legacyDecodingNotImplemented {
                // If we didn't implement legacy decoding for this type, throw the original error from the new decoder
                throw newError
            }
        }

        self = try JSONDecoder().decode(Self.self, from: data)
    }
}

// MARK: PolymorphicSerializable protocol.


/// Protocol for types which can be serialized as polymorphic elements, where the type of each element is read during deserialization so the correct class or struct can be instantiated.  The top-level class typically will implement `classForCode()` to return the class to be instantiated based on the code it is passed by the deserializer, while all classes will implement the other methods.  Each class should return a unique value for `serializableTypeCode`, although this is not enforced.
///
/// Elements of these types will be wrapped in a `PolymorphicSerializableWrapper` struct to be serialized.  They should never be serialized directly (which is why this protocol does not adopt `Serializable`).
///
/// `PolymorphicSerializable` does not support serializing multiple types of a given protocol, because deserialization cannot infer the type to instantiate if all it has to work with is the protocol.  A class hierarchy should be used instead.
public protocol PolymorphicSerializable
{
    /// Serialize the receiver.
    func serialize<T: Serializer>(to serializer: T)

    /// Create a new instance of the receiver from a deserializer.
    init(from deserializer: any Deserializer) throws

    /// PolymorphicSerializable requires a closed set of implementations.
    static var implementations: [SerializableTypeCode: any PolymorphicSerializable.Type] { get }
}

extension PolymorphicSerializable {

    public static var serializableTypeCode: SerializableTypeCode {
        for (i, t) in self.implementations {
            if self == t {
                return i
            }
        }

        fatalError("Unknown implementation \(self): every implementation needs to be listed in `implementations`")
    }

    /// Returns the class to use to create a new instance of the receiver based on the type code for that receiver.
    public static func classForCode(_ code: SerializableTypeCode) -> (any PolymorphicSerializable.Type)? {
        return self.implementations[code]
    }

}

public typealias SerializableTypeCode = UInt


/// A wrapper for a user-defined type which can be serialized as aggregate elements.
fileprivate struct PolymorphicSerializableWrapper<T: PolymorphicSerializable>: Serializable
{
    /// The element being wrapped.
    let value: T

    /// Wrap the element for serialization.
    init(_ value: T)
    {
        self.value = value
    }

    /// Serialize the wrapper - including the type code for the element - and the element.
    func serialize<S: Serializer>(to serializer: S)
    {
        serializer.beginAggregate(2)
        type(of: self.value).serializableTypeCode.serialize(to: serializer)
        self.value.serialize(to: serializer)
        serializer.endAggregate()
    }

    /// Create a new instance of the wrapper with an instance of the wrapped element inside it.
    init(from deserializer: any Deserializer) throws
    {
        try deserializer.beginAggregate(2)
        let code: SerializableTypeCode = try deserializer.deserialize()
        guard let classType = T.classForCode(code) else { throw DeserializerError.incorrectType("Unexpected serializable type code for concrete '\(type(of: T.self))': \(code)") }
        self = PolymorphicSerializableWrapper(try classType.init(from: deserializer) as! T)
    }
}


// MARK: Serialization for built-in types


extension Int: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        self = try deserializer.deserialize()
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(self)
    }
}

extension UInt: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        self = try deserializer.deserialize()
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(self)
    }
}

extension Int32: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        // We use `truncatingBitPattern` here because we encode 32-bit values as normal UInts. It is up to the client to never use this in a way which could lose bits.
        self = Int32(try deserializer.deserialize() as Int)
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(Int(self))
    }
}

extension UInt32: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        // We use `truncatingBitPattern` here because we encode 32-bit values as normal UInts. It is up to the client to never use this in a way which could lose bits.
        self = UInt32(truncatingIfNeeded: try deserializer.deserialize() as UInt)
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(UInt(self))
    }
}

extension Int64: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        // We assume that this is a lossless conversion which should have no type checks.
        self = Int64(try deserializer.deserialize() as Int)
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        // Despite the name here, we expect UInt to always be 64-bits and thus this does not truncate.
        assert(Int64(Int(truncatingIfNeeded: self)) == self)
        serializer.serialize(Int(truncatingIfNeeded: self))
    }
}

extension UInt64: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        // We assume that this is a lossless conversion which should have no type checks.
        self = UInt64(try deserializer.deserialize() as UInt)
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        // Despite the name here, we expect UInt to always be 64-bits and thus this does not truncate.
        assert(UInt64(UInt(truncatingIfNeeded: self)) == self)
        serializer.serialize(UInt(truncatingIfNeeded: self))
    }
}

extension Bool: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        self = try deserializer.deserialize()
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(self)
    }
}

extension Float32: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        self = try deserializer.deserialize()
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(self)
    }
}

extension Float64: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        self = try deserializer.deserialize()
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(self)
    }
}

extension String: Serializable
{
    public init(from deserializer: any Deserializer) throws
    {
        self = try deserializer.deserialize()
    }

    public func serialize<T: Serializer>(to serializer: T)
    {
        serializer.serialize(self)
    }
}

extension RawRepresentable where Self: Serializable, RawValue: Serializable {
    public init(from deserializer: any Deserializer) throws {
        let rawValue: RawValue = try deserializer.deserialize()
        guard let r = Self(rawValue: rawValue) else {
            throw DeserializerError.incorrectType("Unexpected raw value \(rawValue) for type \(Self.self)")
        }

        self = r
    }

    public func serialize<T: Serializer>(to serializer: T) {
        serializer.serialize(self.rawValue)
    }
}

extension Set: Serializable where Element: Serializable & Comparable {
    public func serialize<T: Serializer>(to serializer: T) {
        serializer.serialize(sorted())
    }

    public init(from deserializer: any Deserializer) throws {
        self.init(try deserializer.deserialize() as [Element])
    }
}

extension OrderedSet: Serializable where Element: Serializable {
    public func serialize<T>(to serializer: T) where T : Serializer {
        serializer.serialize(elements)
    }

    public init(from deserializer: any Deserializer) throws {
        self.init(try deserializer.deserialize() as [Element])
    }
}

// MARK: Encoder and Decoder protocols


protocol Encoder: AnyObject
{
    /// The byte array containing the encoded data.
    var bytes: [UInt8] { get }

    /// Append an `Int64` to the encoded bytes.
    func append(_ i: Int64)

    /// Append a `UInt64` to the encoded bytes.
    func append(_ i: UInt64)

    /// Append a `UInt8` to the encoded bytes.
    func append(_ i: UInt8)

    /// Append nil to the encoded bytes.
    func appendNil()

    /// Append a `Bool` to the encoded bytes.
    func append(_ b: Bool)

    /// Append a `Float32` to the encoded bytes.
    func append(_ f: Float32)

    /// Append a `Float64` to the encoded bytes.
    func append(_ f: Float64)

    /// Append a `String` to the encoded bytes.
    func append(_ s: String)

    /// Append an array of bytes to the encoded bytes.
    func append(_ dataBytes: [UInt8])

    /// Append an array of elements to the encoded bytes.  `encode` must be a closure which will encode the element passed to it from the `Encoder`.
    func append<T>(_ array: [T], encode: (T) -> Void)

    /// Append a dictionary of keys and values to the encoded bytes.  `encodeKey` and `encodeValue` must be closures which will encode the elements passed to them from the `Encoder`.
    func append<Tk: Comparable, Tv>(_ dict: [Tk: Tv], encodeKey: (Tk) -> Void, encodeValue: (Tv) -> Void)

    /// Append extended data to the encoded bytes.
    func appendExtended(type: Int8, data: [UInt8])

    /// Begin adding an array of elements to the encoded bytes, starting with the number of elements.
    func beginArray(_ count: Int)

    /// End adding an array of elements to the encoded bytes.
    func endArray()
}


protocol Decoder: AnyObject
{
    /// Decode an `Int64` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not an `Int64`.
    func readInt64() -> Int64?

    /// Decode a `UInt64` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `UInt64`.
    func readUInt64() -> UInt64?

    /// Decode a `UInt8` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `UInt8`.
    func readByte() -> UInt8?

    /// Decode `nil` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `nil`.
    func readNil() -> Bool

    /// Decode a `Bool` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `Bool`.
    func readBool() -> Bool?

    /// Decode a `Float32` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `Float32`.
    func readFloat32() -> Float32?

    /// Decode a `Float64` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `Float64`.
    func readFloat64() -> Float64?

    /// Decode a `String` from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not a `String`.
    func readString() -> String?

    /// Decode an array of bytes from the encoded bytes and consume that item.  Returns nil and does not consume the next item if it is not an array of bytes.
    func readBinary() -> [UInt8]?

    /// Decode an array of elements from the encoded bytes and consume them.  Returns nil if the next item is not the beginning of an array or if anything in the array cannot be decoded - however the decoder may be left in a bad state if this happens.
    /// - parameter decodeElement: Called to decode each element of the array. This closure should throw an exception if it fails to decode an element.
    func readArray<T>(_ decodeElement: () throws -> T) -> [T]?

    /// Decode an dictionary of keys and values from the encoded bytes and consume them.  Returns nil if the next item is not the beginning of a dictionary or if anything in the dictionary cannot be decoded - however the decoder may be left in a bad state if this happens.
    /// - parameter decodeKey: Called to decode each key of the dictionary. This closure should throw an exception if it fails to decode a key.
    /// - parameter decodeValue: Called to decode each value of the dictionary. This closure should throw an exception if it fails to decode a value.
    func readDictionary<Tk, Tv>(_ decodeKey: () throws -> Tk, _ decodeValue: () throws -> Tv) -> [Tk: Tv]?

    /// Decode extended data from the encoded bytes, returning the type code for the data, and a byte array of the data itself.
    func readExtended() -> (type: Int8, data: [UInt8])?

    /// Begin reading an array of elements from the encoded bytes, by getting the number of elements.  Returns nil if the next item is not the beginning of an array.
    func readBeginArray() -> Int?
}