Repository: vapor/vapor
File: Sources/Vapor/Validation/Validators/Case.swift (Swift)

Code before:
extension ValidatorResults {
    /// `ValidatorResult` of a validator thaat validates whether the data can be represented as a specific Enum case.
    public struct Case<T, E> where E: RawRepresentable & CaseIterable, E.RawValue == T, T: CustomStringConvertible {
        /// The type of the enum to check.
        let enumType: E.Type
        /// The raw value that would be tested agains the enum type.
        let rawValue: T
    }
}

extension ValidatorResults.Case: ValidatorResult {
    public var isFailure: Bool {
        return enumType.init(rawValue: rawValue) == nil
    }

    public var successDescription: String? {
        "is \(E.self)"
    }

    public var failureDescription: String? {
        var cases = E.allCases.map { "\($0.rawValue)" }
        var suffix = ""
        if cases.count > 1 {
            suffix = " or \(cases.removeLast())"
        }
        return "is not \(cases.joined(separator: ", "))\(suffix)."
    }
}


Review comment (bug):
Most annoying nit of all time: can we have an oxford comma here? >_<

You should  be able to copy `makeDescription` from the `.in` validator (`In.swift`) which supports both successDescription and failureDescription and includes the comma:

```swift
    func makeDescription(not: Bool) -> String {
        let description: String
        switch self.items.count {
        case 1:
            description = self.items[0].description
        case 2:
            description = "\(self.items[0].description) or \(self.items[1].description)"
        default:
            let first = self.items[0..<(self.items.count - 1)]
                .map { $0.description }.joined(separator: ", ")
            let last = self.items[self.items.count - 1].description
            description = "\(first), or \(last)"
        }
        return "is\(not ? " not" : " ") \(description)"
    }
```

Code after:
extension ValidatorResults {
    /// `ValidatorResult` of a validator thaat validates whether the data can be represented as a specific Enum case.
    public struct Case<T, E> where E: RawRepresentable & CaseIterable, E.RawValue == T, T: CustomStringConvertible {
        /// The type of the enum to check.
        let enumType: E.Type
        /// The raw value that would be tested agains the enum type.
        let rawValue: T
    }
}

extension ValidatorResults.Case: ValidatorResult {
    public var isFailure: Bool {
        return enumType.init(rawValue: rawValue) == nil
    }

    public var successDescription: String? {
        makeDescription(not: false)
    }

    public var failureDescription: String? {
        makeDescription(not: true)
    }

    func makeDescription(not: Bool) -> String {
        let items = E.allCases.map { "\($0.rawValue)" }
        let description: String
        switch items.count {
        case 1:
            description = items[0].description
        case 2:
            description = "\(items[0].description) or \(items[1].description)"
        default:
            let first = items[0..<(items.count - 1)]
                .map { $0.description }.joined(separator: ", ")
            let last = items[items.count - 1].description
            description = "\(first), or \(last)"
        }
        return "is\(not ? " not" : "") \(description)"
    }
}