@@ -51,11 +51,6 @@ Considered for sordid history).
51
51
The ` [U]Int128 ` types conform to ` AtomicRepresentable ` on targets with
52
52
` _hasAtomicBitWidth(_128) ` set (notably x86\_ 64, arm64, and arm64\_ 32).
53
53
54
- The ` [U]Int128 ` types conform to ` Codable ` ; however, many existing encoders
55
- and decoders do not support such large integer types. Therefore they are
56
- encoded as a pair of 64b integers. This pair is always in little-endian
57
- order, regardless of the endianness of the architecture.
58
-
59
54
The actual API of the types is uninteresting; they are entirely constrained by
60
55
their protocol conformances. Notably, these types conform to the following
61
56
protocols, and hence to any protocol that they refine:
@@ -77,6 +72,78 @@ protocols, and hence to any protocol that they refine:
77
72
¹ For the purposes of this discussion, arm64\_ 32 and similar architectures
78
73
are "64b targets."
79
74
75
+ ### Codable details
76
+
77
+ An earlier version of this proposal conformed ` [U]Int128 ` to ` Codable `
78
+ with a representation as a pair of ` [U]Int64 ` values. During the first review
79
+ period several people made excellent points:
80
+
81
+ - Making it possible for encoders to customize how they represent these types
82
+ is desirable. Some cannot represent all 64b values or might prefer to use a
83
+ string representation, others might prefer to treat 128b integers as native
84
+ values to encode.
85
+
86
+ - If we make it customizable but provide a default behavior, some decoders
87
+ would have to support that default as well as their desired representation,
88
+ for compatibility with any encodings created between when we added support
89
+ and when they defined their preferred encoding.
90
+
91
+ For this reason, the proposal has been updated to add new protocol requirements
92
+ for encoders and decoders to support ` [U]Int128 ` , but with default
93
+ implementations that throw an EncodingError or DecodingError unconditionally,
94
+ allowing implementations to choose their preferred behavior when they add
95
+ support without worrying about compatibility with a defaulted implementation.
96
+
97
+ Thus, the following requirements will be added:
98
+ ``` swift
99
+ protocol KeyedEncodingContainerProtocol {
100
+ mutating func encode (_ value : Int128, forKey key : Key ) throws
101
+ mutating func encode (_ value : UInt128, forKey key : Key ) throws
102
+ mutating func encodeIfPresent (_ value : Int128? , forKey key : Key ) throws
103
+ mutating func encodeIfPresent (_ value : UInt128? , forKey key : Key ) throws
104
+ // And matching changes to KeyedEncodingContainer<Key>
105
+ }
106
+
107
+ protocol KeyedDecodingContainerProtocol {
108
+ func decode (_ type : Int128.Type , forKey key : Key ) throws -> Int128
109
+ func decode (_ type : UInt128.Type , forKey key : Key ) throws -> UInt128
110
+ func decodeIfPresent (_ type : Int128.Type , forKey key : Key ) throws -> Int128?
111
+ func decodeIfPresent (_ type : UInt128.Type , forKey key : Key ) throws -> UInt128?
112
+ // And matching changes to KeyedDecodingContainer<Key>
113
+ }
114
+
115
+ protocol UnkeyedEncodingContainer {
116
+ mutating func encode (_ value : Int128) throws
117
+ mutating func encode (_ value : UInt128) throws
118
+ mutating func encode <T : Sequence >(
119
+ contentsOf sequence : T
120
+ ) throws where T.Element == Int128
121
+ mutating func encode <T : Sequence >(
122
+ contentsOf sequence : T
123
+ ) throws where T.Element == UInt128
124
+ }
125
+
126
+ protocol UnkeyedDecodingContainer {
127
+ mutating func decode (_ type : Int128.Type ) throws -> Int128
128
+ mutating func decode (_ type : UInt128.Type ) throws -> UInt128
129
+ mutating func decodeIfPresent (_ type : Int128.Type ) throws -> Int128?
130
+ mutating func decodeIfPresent (_ type : UInt128.Type ) throws -> UInt128?
131
+ }
132
+
133
+ protocol SingleValueEncodingContainer {
134
+ mutating func encode (_ value : Int128) throws
135
+ mutating func encode (_ value : UInt128) throws
136
+ }
137
+
138
+ protocol SingleValueDecodingContainer {
139
+ func decode (_ type : Int128.Type ) throws -> Int128
140
+ func decode (_ type : UInt128.Type ) throws -> UInt128
141
+ }
142
+ ```
143
+ and given default implementations. The default encode implementations throw
144
+ ` EncodingError.invalidValue ` , and the default decode implementations throw
145
+ ` DecodingError.typeMismatch ` .
146
+
80
147
## Source compatibility
81
148
82
149
This proposal has no effect on source compatibility.
@@ -126,14 +193,6 @@ While other fixed-width integer types are interesting, 128 bits is a couple
126
193
orders of magnitude more useful than all the others for general-purpose
127
194
software at this point in time.
128
195
129
- ### Codable conformance
130
- Because many existing encoders and decoders do not already support 128b
131
- integers, we use a pair of 64b integers instead. To maximize compatibility,
132
- or to improve human-readability, we could instead encode these types as
133
- decimal or hexadecimal strings. However, this would be somewhat less
134
- efficient in some use cases, and it is possible for users to achieve the
135
- same effect by converting to a string before encoding.
136
-
137
196
### NSNumber bridging
138
197
` [U]Int128 ` will not bridge to ` NSNumber ` . In the future, Swift will need
139
198
a careful rethinking of how best to handle type-erased numbers, but we don't
@@ -142,3 +201,11 @@ that isn't supported on all platforms. In addition, the most common use for
142
201
such bridging, unpacking type-erased fields from encoded dictionaries, is
143
202
somewhat moot since most existing coders do not support 128b integers. We
144
203
will likely revisit this more holistically in the future.
204
+
205
+ ### Codable errors
206
+ It would be nice to introduce new ` unsupportedType ` error cases for the
207
+ default Codable conformances, but we cannot add new cases with associated
208
+ values and constrained availability to existing enums, which prevents
209
+ attaching context or a useful debug description. It's more useful for users
210
+ if we use existing error cases ` invalidValue ` and ` typeMismatch ` but put an
211
+ actionable message in that description field.
0 commit comments