@@ -41,20 +41,20 @@ extension StructuredFieldDecoder {
41
41
extension StructuredFieldDecoder {
42
42
/// Attempt to decode an object from a structured header field.
43
43
///
44
- /// This method will attempt to guess what kind of structured header field is being
45
- /// parsed based on the structure of `type`. This is useful for quick prototyping, but
46
- /// generally this method should be avoided in favour of one of the other `decode`
47
- /// methods on this type.
48
- ///
49
44
/// - parameters:
50
45
/// - type: The type of the object to decode.
51
46
/// - data: The bytes of the structured header field.
52
47
/// - throws: If the header field could not be parsed, or could not be decoded.
53
48
/// - returns: An object of type `StructuredField`.
54
- public func decode< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
55
- let parser = StructuredFieldParser ( data)
56
- let decoder = _StructuredFieldDecoder ( parser, keyDecodingStrategy: self . keyDecodingStrategy)
57
- return try type. init ( from: decoder)
49
+ public func decode< StructuredField: StructuredHeaderField , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
50
+ switch StructuredField . structuredFieldType {
51
+ case . item:
52
+ return try self . decodeItemField ( from: data)
53
+ case . list:
54
+ return try self . decodeListField ( from: data)
55
+ case . dictionary:
56
+ return try self . decodeDictionaryField ( from: data)
57
+ }
58
58
}
59
59
60
60
/// Attempt to decode an object from a structured header dictionary field.
@@ -64,7 +64,7 @@ extension StructuredFieldDecoder {
64
64
/// - data: The bytes of the structured header field.
65
65
/// - throws: If the header field could not be parsed, or could not be decoded.
66
66
/// - returns: An object of type `StructuredField`.
67
- public func decodeDictionaryField< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
67
+ private func decodeDictionaryField< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
68
68
let parser = StructuredFieldParser ( data)
69
69
let decoder = _StructuredFieldDecoder ( parser, keyDecodingStrategy: self . keyDecodingStrategy)
70
70
try decoder. parseDictionaryField ( )
@@ -78,7 +78,7 @@ extension StructuredFieldDecoder {
78
78
/// - data: The bytes of the structured header field.
79
79
/// - throws: If the header field could not be parsed, or could not be decoded.
80
80
/// - returns: An object of type `StructuredField`.
81
- public func decodeListField< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
81
+ private func decodeListField< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
82
82
let parser = StructuredFieldParser ( data)
83
83
let decoder = _StructuredFieldDecoder ( parser, keyDecodingStrategy: self . keyDecodingStrategy)
84
84
try decoder. parseListField ( )
@@ -92,7 +92,7 @@ extension StructuredFieldDecoder {
92
92
/// - data: The bytes of the structured header field.
93
93
/// - throws: If the header field could not be parsed, or could not be decoded.
94
94
/// - returns: An object of type `StructuredField`.
95
- public func decodeItemField< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
95
+ private func decodeItemField< StructuredField: Decodable , BaseData: RandomAccessCollection > ( _ type: StructuredField . Type = StructuredField . self, from data: BaseData ) throws -> StructuredField where BaseData. Element == UInt8 , BaseData. SubSequence: Hashable {
96
96
let parser = StructuredFieldParser ( data)
97
97
let decoder = _StructuredFieldDecoder ( parser, keyDecodingStrategy: self . keyDecodingStrategy)
98
98
try decoder. parseItemField ( )
@@ -148,34 +148,24 @@ extension _StructuredFieldDecoder: Decoder {
148
148
}
149
149
150
150
func container< Key> ( keyedBy type: Key . Type ) throws -> KeyedDecodingContainer < Key > where Key: CodingKey {
151
- if self . currentElement == nil {
152
- // First parse. This may be a dictionary, but depending on the keys this may also be list or item.
153
- // We can't really detect this (Key isn't caseiterable) so we just kinda have to hope. Users can tell
154
- // us with alternative methods if we're wrong.
155
- try self . parseDictionaryField ( )
156
- }
157
-
158
151
switch self . currentElement! {
159
152
case . dictionary( let dictionary) :
160
153
return KeyedDecodingContainer ( DictionaryKeyedContainer ( dictionary, decoder: self ) )
161
154
case . item( let item) :
162
155
return KeyedDecodingContainer ( KeyedItemDecoder ( item, decoder: self ) )
156
+ case . list( let list) :
157
+ return KeyedDecodingContainer ( KeyedTopLevelListDecoder ( list, decoder: self ) )
163
158
case . innerList( let innerList) :
164
159
return KeyedDecodingContainer ( KeyedInnerListDecoder ( innerList, decoder: self ) )
165
160
case . parameters( let parameters) :
166
161
return KeyedDecodingContainer ( ParametersDecoder ( parameters, decoder: self ) )
167
- case . bareItem, . bareInnerList, . list :
162
+ case . bareItem, . bareInnerList:
168
163
// No keyed container for these types.
169
164
throw StructuredHeaderError . invalidTypeForItem
170
165
}
171
166
}
172
167
173
168
func unkeyedContainer( ) throws -> UnkeyedDecodingContainer {
174
- if self . currentElement == nil {
175
- // First parse, this is a list header.
176
- try self . parseListField ( )
177
- }
178
-
179
169
// We have unkeyed containers for lists, inner lists, and bare inner lists.
180
170
switch self . currentElement! {
181
171
case . list( let items) :
@@ -191,11 +181,6 @@ extension _StructuredFieldDecoder: Decoder {
191
181
}
192
182
193
183
func singleValueContainer( ) throws -> SingleValueDecodingContainer {
194
- if self . currentElement == nil {
195
- // First parse, this is a an item header.
196
- try self . parseItemField ( )
197
- }
198
-
199
184
// We have single value containers for items and bareItems.
200
185
switch self . currentElement! {
201
186
case . item( let item) :
@@ -256,16 +241,24 @@ extension _StructuredFieldDecoder {
256
241
return . innerList( innerList)
257
242
}
258
243
case . list( let list) :
259
- guard let offset = key. intValue, offset < list. count else {
244
+ if let offset = key. intValue {
245
+ guard offset < list. count else {
246
+ throw StructuredHeaderError . invalidTypeForItem
247
+ }
248
+ let index = list. index ( list. startIndex, offsetBy: offset)
249
+ switch list [ index] {
250
+ case . item( let item) :
251
+ return . item( item)
252
+ case . innerList( let innerList) :
253
+ return . innerList( innerList)
254
+ }
255
+ } else if key. stringValue == " items " {
256
+ // Oh, the outer layer is keyed. That's fine, just put ourselves
257
+ // back on the stack.
258
+ return . list( list)
259
+ } else {
260
260
throw StructuredHeaderError . invalidTypeForItem
261
261
}
262
- let index = list. index ( list. startIndex, offsetBy: offset)
263
- switch list [ index] {
264
- case . item( let item) :
265
- return . item( item)
266
- case . innerList( let innerList) :
267
- return . innerList( innerList)
268
- }
269
262
case . item( let item) :
270
263
// Two keys, "item" and "parameters".
271
264
switch key. stringValue {
0 commit comments