<commit_before>//
//  ExpirationExtractor.swift
//  PAYJP
//
//  Created by <NAME> on 2019/07/18.
//  Copyright © 2019 PAY, Inc. All rights reserved.
//

import Foundation

protocol ExpirationExtractorType {
    /// フォーマットされた文字列を月と年に分離する
    /// - parameter expiration: MM/yy にフォーマットされた文字列。
    /// - throws: 月は 1~12 の間の数字ではなかったら、エラー `monthOverflow` を投げ出します
    /// - returns: 月と年の tuple 、インプットは想定中なフォーマットではなかったら nil で返します。
    func extract(expiration: String?) throws -> (month: String, year: String)?
}

struct ExpirationExtractor: ExpirationExtractorType {
    
    let formatter: ExpirationFormatterType
    
    init(formatter: ExpirationFormatterType = ExpirationFormatter()) {
        self.formatter = formatter
    }
    
    func extract(expiration: String?) throws -> (month: String, year: String)? {
        if let expiration = expiration, !expiration.isEmpty {
            let monthYear = expiration.split(separator: "/").map(String.init)
            
            if monthYear.count < 2 { return nil }
            
            let month = monthYear[0]
            let year = monthYear[1]
            
            let intMonth = Int(month)
            let intYear = Int(year)
            
            if intMonth == nil || intYear == nil { return nil }
            
            if !(1...12 ~= intMonth ?? 0) { throw ExpirationExtractorError.monthOverflow }
            
            return (month, year)
        }
        
        return nil
    }
}

enum ExpirationExtractorError: Error {
    case monthOverflow
}<commit_msg>Append "20" before going out.<commit_after>//
//  ExpirationExtractor.swift
//  PAYJP
//
//  Created by <NAME> on 2019/07/18.
//  Copyright © 2019 PAY, Inc. All rights reserved.
//

import Foundation

protocol ExpirationExtractorType {
    /// フォーマットされた文字列を月と年に分離する
    /// - parameter expiration: MM/yy にフォーマットされた文字列。
    /// - throws: 月は 1~12 の間の数字ではなかったら、エラー `monthOverflow` を投げ出します
    /// - returns: 月と年の tuple 、インプットは想定中なフォーマットではなかったら nil で返します。
    func extract(expiration: String?) throws -> (month: String, year: String)?
}

struct ExpirationExtractor: ExpirationExtractorType {
    
    let formatter: ExpirationFormatterType
    
    init(formatter: ExpirationFormatterType = ExpirationFormatter()) {
        self.formatter = formatter
    }
    
    func extract(expiration: String?) throws -> (month: String, year: String)? {
        if let expiration = expiration, !expiration.isEmpty {
            let monthYear = expiration.split(separator: "/").map(String.init)
            
            if monthYear.count < 2 { return nil }
            
            let month = monthYear[0]
            let year = monthYear[1]
            
            let intMonth = Int(month)
            let intYear = Int(year)
            
            if intMonth == nil || intYear == nil { return nil }
            
            if !(1...12 ~= intMonth ?? 0) { throw ExpirationExtractorError.monthOverflow }
            
            return (month, "20" + year)
        }
        
        return nil
    }
}

enum ExpirationExtractorError: Error {
    case monthOverflow
}
{'fraction_non_alphanumeric': 0.10274636510500808, 'fraction_numerical': 0.015508885298869143, 'mean_word_length': 2.059288537549407, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, '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': '359930', 'n_tokens_mistral': 1039, 'n_tokens_neox': 957, 'n_words': 231}