Created
October 11, 2024 09:09
Revisions
-
d-date created this gist
Oct 11, 2024 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,67 @@ enum CreditCardBrand: String { enum Pattern { static let visa = #"^4[0-9]{12}(?:[0-9]{3})?"# static let master = #"^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$"# static let amex = #"^3[47][0-9]{13}$"# static let diners = #"^3(?:0[0-5]|[68][0-9])[0-9]{11,13}$"# static let discover = #"^6(?:011|5[0-9]{2})[0-9]{12}$"# static let jcb = #"^(?:2131|1800|35\d{3})\d{7}"# } case visa = "Visa" case master = "Master" case amex = "Amex" case diners = "Diners" case discover = "Discover" case jcb = "JCB" init?(cardBrand: CafeAPIClient.CreditCard.CardBrand) { switch cardBrand { case .americanExpress: self = .amex case .dinersClub: self = .diners case .discover: self = .discover case .jcb: self = .jcb case .masterCard: self = .master case .visa: self = .visa case .unknown: return nil } } init?(cardNumber: String) { switch cardNumber { case Regex(pattern: Pattern.visa): self = .visa case Regex(pattern: Pattern.master): self = .master case Regex(pattern: Pattern.amex): self = .amex case Regex(pattern: Pattern.diners): self = .diners case Regex(pattern: Pattern.discover): self = .discover case Regex(pattern: Pattern.jcb): self = .jcb default: return nil } } } This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,38 @@ import Foundation protocol RegularExpressionMatchable { func match(regex: Regex) -> Bool } extension String: RegularExpressionMatchable { func match(regex: Regex) -> Bool { regex.match(string: self) } } func ~= <T: RegularExpressionMatchable>(pattern: Regex, matchable: T) -> Bool { matchable.match(regex: pattern) } struct Regex { let pattern: String let options: NSRegularExpression.Options init(pattern: String, options: NSRegularExpression.Options = []) { self.pattern = pattern self.options = options } private var matcher: NSRegularExpression { do { return try NSRegularExpression(pattern: pattern, options: options) } catch { print(error) fatalError() } } func match(string: String, options: NSRegularExpression.MatchingOptions = []) -> Bool { matcher.firstMatch(in: string, options: options, range: .init(location: 0, length: string.count)) != nil } }