in Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift [617:722]
func encode<T>(_ value: T, forKey key: String) throws where T: Encodable {
let key = self.sanitizeKey(key)
switch value {
case let value as UInt8:
try self.encode(value, forKey: key)
case let value as Int8:
try self.encode(value, forKey: key)
case let value as UInt16:
try self.encode(value, forKey: key)
case let value as Int16:
try self.encode(value, forKey: key)
case let value as UInt32:
try self.encode(value, forKey: key)
case let value as Int32:
try self.encode(value, forKey: key)
case let value as UInt64:
try self.encode(value, forKey: key)
case let value as Int64:
try self.encode(value, forKey: key)
case let value as Int:
try self.encode(value, forKey: key)
case let value as UInt:
try self.encode(value, forKey: key)
case let value as Float:
try self.encode(value, forKey: key)
case let value as Double:
try self.encode(value, forKey: key)
case let value as String:
try self.encode(value, forKey: key)
case let value as Bool:
try self.encode(value, forKey: key)
case let value as Data:
try self.encode(value, forKey: key)
case let value as Decimal:
try self.encode(value, forKey: key)
default:
// Ok, we don't know what this is. This can only happen for a dictionary, or
// for anything with parameters, or for lists, or for inner lists.
switch self.currentStackEntry.storage {
case .dictionaryHeader:
// Ah, this is a dictionary, good to know. Initialize the storage, keep going.
self.currentStackEntry.storage = .dictionary([:])
fallthrough
case .dictionary:
// This must be an item or inner list.
self.push(key: .init(stringValue: key), newStorage: .itemOrInnerList([:]))
try value.encode(to: self)
try self.pop()
case .item:
guard key == "parameters" else {
throw StructuredHeaderError.invalidTypeForItem
}
self.push(key: .init(stringValue: key), newStorage: .parameters([:]))
try value.encode(to: self)
try self.pop()
case .innerList:
switch key {
case "items":
self.push(key: .init(stringValue: key), newStorage: .bareInnerList([]))
try value.encode(to: self)
try self.pop()
case "parameters":
self.push(key: .init(stringValue: key), newStorage: .parameters([:]))
try value.encode(to: self)
try self.pop()
default:
throw StructuredHeaderError.invalidTypeForItem
}
case .itemOrInnerList(let params):
switch key {
case "items":
// We're a list!
self.currentStackEntry.storage = .innerList(InnerList(bareInnerList: [], parameters: params))
self.push(key: .init(stringValue: key), newStorage: .bareInnerList([]))
try value.encode(to: self)
try self.pop()
case "parameters":
self.push(key: .init(stringValue: key), newStorage: .parameters([:]))
try value.encode(to: self)
try self.pop()
default:
throw StructuredHeaderError.invalidTypeForItem
}
case .listHeader:
switch key {
case "items":
// Ok, we're a list. Good to know.
self.push(key: .init(stringValue: key), newStorage: .list([]))
try value.encode(to: self)
try self.pop()
default:
throw StructuredHeaderError.invalidTypeForItem
}
case .list, .itemHeader, .bareInnerList,
.parameters:
throw StructuredHeaderError.invalidTypeForItem
}
}
}