<commit_before>//
//  Validation.swift
//  Reactant
//
//  Created by <NAME> on 09/09/16.
//  Copyright © 2016 CocoaPods. All rights reserved.
//

public protocol RuleValidationError: Error { }

public enum DefaultValidationError: RuleValidationError {
    case invalid
}

public enum EmailValidationError: RuleValidationError {
    case empty
    case invalid
}

public struct Rule<T, E: RuleValidationError> {
    public let validate: (T) -> E?

    public init(validate: @escaping (T) -> E?) {
        self.validate = validate
    }

    public func test(_ value: T) -> Bool {
        return validate(value) == nil
    }

    public func run(_ value: T) -> Result<T, E> {
        if let error = validate(value) {
            return .failure(error)
        } else {
            return .success(value)
        }
    }
}

public struct Rules {
    public static let notEmpty = Rule<String?, DefaultValidationError> { value in
        guard let value = value, value.characters.isEmpty == false else {
            return .invalid
        }

        return nil
    }

    public static func minLength(length: Int) -> Rule<String?, DefaultValidationError> {
        return Rule { value in
            guard let value = value, value.characters.count >= length else {
                return .invalid
            }
            return nil
        }
    }

    public static let email = Rule<String?, EmailValidationError> { value in
        guard Rules.notEmpty.test(value) else {
            return .empty
        }

        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
        let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)

        guard predicate.evaluate(with: value) else { return .invalid }
        
        return nil
    }
}
<commit_msg>Fix minLength rule api.<commit_after>//
//  Validation.swift
//  Reactant
//
//  Created by <NAME> on 09/09/16.
//  Copyright © 2016 CocoaPods. All rights reserved.
//

public protocol RuleValidationError: Error { }

public enum DefaultValidationError: RuleValidationError {
    case invalid
}

public enum EmailValidationError: RuleValidationError {
    case empty
    case invalid
}

public struct Rule<T, E: RuleValidationError> {
    public let validate: (T) -> E?

    public init(validate: @escaping (T) -> E?) {
        self.validate = validate
    }

    public func test(_ value: T) -> Bool {
        return validate(value) == nil
    }

    public func run(_ value: T) -> Result<T, E> {
        if let error = validate(value) {
            return .failure(error)
        } else {
            return .success(value)
        }
    }
}

public struct Rules {
    public static let notEmpty = Rule<String?, DefaultValidationError> { value in
        guard let value = value, value.characters.isEmpty == false else {
            return .invalid
        }

        return nil
    }

    public static func minLength(_ length: Int) -> Rule<String?, DefaultValidationError> {
        return Rule { value in
            guard let value = value, value.characters.count >= length else {
                return .invalid
            }
            return nil
        }
    }

    public static let email = Rule<String?, EmailValidationError> { value in
        guard Rules.notEmpty.test(value) else {
            return .empty
        }

        let emailRegex = "[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}"
        let predicate = NSPredicate(format: "SELF MATCHES %@", emailRegex)

        guard predicate.evaluate(with: value) else { return .invalid }
        
        return nil
    }
}

{'fraction_non_alphanumeric': 0.10996082820369334, 'fraction_numerical': 0.008953553441522105, 'mean_word_length': 2.0660377358490565, 'pattern_counts': {'":': 0, '<': 15, '<?xml version=': 0, '>': 27, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2111856', 'n_tokens_mistral': 1067, 'n_tokens_neox': 1012, 'n_words': 302}