func encode()

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
            }
        }
    }