Repository: vapor/vapor
File: Sources/Vapor/Multipart/FormDataDecoder.swift (Swift)

Code before:
private final class FormDataDecoderContext {
    var parts: [MultipartPart]
    init(parts: [MultipartPart]) {
        self.parts = parts
    }

    func decode<D>(_ decodable: D.Type, at codingPath: [CodingKey]) throws -> D where D: Decodable {
        guard let convertible = D.self as? MultipartPartConvertible.Type else {
            throw MultipartError.convertibleType(D.self)
        }

        let part: MultipartPart
        switch codingPath.count {
        case 1:
            let name = codingPath[0].stringValue
            guard let p = parts.firstPart(named: name) else {
                throw MultipartError.missingPart(name)
            }
            part = p
        case 2:
            let name = codingPath[0].stringValue + "[]"
            guard let offset = codingPath[1].intValue else {
              throw MultipartError.nesting
            }
            guard let p = parts.allParts(named: name)[safe: offset] else {
              throw MultipartError.missingPart("\(codingPath[1].stringValue)")
            }
            part = p
        default:
            throw MultipartError.nesting
        }

        guard let any = convertible.init(multipart: part) else {
            throw MultipartError.convertiblePart(D.self, part)
        }
        return any as! D
    }
}


private struct _FormDataDecoder: Decoder {
    var codingPath: [CodingKey]
    var userInfo: [CodingUserInfoKey: Any] {
        return [:]
    }
    let multipart: FormDataDecoderContext

    init(multipart: FormDataDecoderContext, codingPath: [CodingKey]) {
        self.multipart = multipart
        self.codingPath = codingPath
    }

Review comment (suggestion):
Nit - style guide is 4 spaces
```suggestion
                throw MultipartError.missingPart("\(codingPath[1].stringValue)")
```

Code after:
private final class FormDataDecoderContext {
    var parts: [MultipartPart]
    init(parts: [MultipartPart]) {
        self.parts = parts
    }

    func decode<D>(_ decodable: D.Type, at codingPath: [CodingKey]) throws -> D where D: Decodable {
        guard let convertible = D.self as? MultipartPartConvertible.Type else {
            throw MultipartError.convertibleType(D.self)
        }

        let part: MultipartPart
        switch codingPath.count {
        case 1:
            let name = codingPath[0].stringValue
            guard let p = parts.firstPart(named: name) else {
                throw MultipartError.missingPart(name)
            }
            part = p
        case 2:
            let name = codingPath[0].stringValue + "[]"
            guard let offset = codingPath[1].intValue else {
                throw MultipartError.nesting
            }
            guard let p = parts.allParts(named: name)[safe: offset] else {
                throw MultipartError.missingPart("\(codingPath[1].stringValue)")
            }
            part = p
        default:
            throw MultipartError.nesting
        }

        guard let any = convertible.init(multipart: part) else {
            throw MultipartError.convertiblePart(D.self, part)
        }
        return any as! D
    }
}


private struct _FormDataDecoder: Decoder {
    var codingPath: [CodingKey]
    var userInfo: [CodingUserInfoKey: Any] {
        return [:]
    }
    let multipart: FormDataDecoderContext

    init(multipart: FormDataDecoderContext, codingPath: [CodingKey]) {
        self.multipart = multipart
        self.codingPath = codingPath
    }