diff --git a/CreditCardFormatter.xcodeproj/project.pbxproj b/CreditCardFormatter.xcodeproj/project.pbxproj index 0d17f2c..18aa9e8 100644 --- a/CreditCardFormatter.xcodeproj/project.pbxproj +++ b/CreditCardFormatter.xcodeproj/project.pbxproj @@ -32,6 +32,7 @@ 65DE266023A2FD8700916E9C /* DinersClubInternationalCreditCardFormat.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DE265F23A2FD8700916E9C /* DinersClubInternationalCreditCardFormat.swift */; }; 65DE266223A533B300916E9C /* DinersClubInternationalCreditCardFormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DE266123A533B300916E9C /* DinersClubInternationalCreditCardFormatTests.swift */; }; 65DE34132351018400B9F313 /* UnknownCreditCardFormatTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65DE34122351018400B9F313 /* UnknownCreditCardFormatTests.swift */; }; + 876A74802CE536A200B7BB5D /* CreditCardBrand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 876A747F2CE536A200B7BB5D /* CreditCardBrand.swift */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -74,6 +75,7 @@ 65DE265F23A2FD8700916E9C /* DinersClubInternationalCreditCardFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DinersClubInternationalCreditCardFormat.swift; sourceTree = ""; }; 65DE266123A533B300916E9C /* DinersClubInternationalCreditCardFormatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DinersClubInternationalCreditCardFormatTests.swift; sourceTree = ""; }; 65DE34122351018400B9F313 /* UnknownCreditCardFormatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnknownCreditCardFormatTests.swift; sourceTree = ""; }; + 876A747F2CE536A200B7BB5D /* CreditCardBrand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditCardBrand.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -181,8 +183,9 @@ 65D0DD992399C7C300E6B465 /* DiscoverCreditCardFormat.swift */, 65DE265D23A2FBA900916E9C /* JCBCreditCardFormat.swift */, 658A37C32399B5F5001B79FE /* MasterCardCreditCardFormat.swift */, - 65CCBE66234A2F0D0072B498 /* UnknownCreditCardFormat.swift */, 650342A82329201500F5E01C /* VISACreditCardFormat.swift */, + 65CCBE66234A2F0D0072B498 /* UnknownCreditCardFormat.swift */, + 876A747F2CE536A200B7BB5D /* CreditCardBrand.swift */, ); path = Formats; sourceTree = ""; @@ -331,6 +334,7 @@ 650342A6232849A000F5E01C /* CreditCardFormat.swift in Sources */, 65DE266023A2FD8700916E9C /* DinersClubInternationalCreditCardFormat.swift in Sources */, 658A37C42399B5F5001B79FE /* MasterCardCreditCardFormat.swift in Sources */, + 876A74802CE536A200B7BB5D /* CreditCardBrand.swift in Sources */, 650342A92329201500F5E01C /* VISACreditCardFormat.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/CreditCardFormatter/CreditCardFormat.swift b/Sources/CreditCardFormatter/CreditCardFormat.swift index 06184a1..d029125 100644 --- a/Sources/CreditCardFormatter/CreditCardFormat.swift +++ b/Sources/CreditCardFormatter/CreditCardFormat.swift @@ -28,7 +28,8 @@ import Foundation public protocol CreditCardFormat { var blocks: [Int] { get } - var brand: String { get } + var brand: CreditCardBrand { get } + var cvvLength: Int { get } func shouldFormat(_ string: String) -> Bool func isValid(_ string: String) -> Bool } diff --git a/Sources/CreditCardFormatter/CreditCardFormatter.swift b/Sources/CreditCardFormatter/CreditCardFormatter.swift index c5ae4f0..49130d0 100644 --- a/Sources/CreditCardFormatter/CreditCardFormatter.swift +++ b/Sources/CreditCardFormatter/CreditCardFormatter.swift @@ -68,10 +68,20 @@ public final class CreditCardFormatter { return formatter.formattedString(from: strippedString, delimiter: delimiter, repeatLastBlock: shouldRepeatLastBlock(for: formatter)) } + public func formattedMaskedString(from string: String, maskCharacter: Character) -> String { + let maskedString = string.filter { $0.isWholeNumber || $0 == maskCharacter } + let formatter = selectFormatter(from: maskedString) + return formatter.formattedString( + from: maskedString, + delimiter: delimiter, + repeatLastBlock: shouldRepeatLastBlock(for: formatter) + ) + } + public func brand(from string: String) -> String { let strippedString = removeNonDecimalDigits(from: string) let formatter = selectFormatter(from: strippedString) - return formatter.brand + return formatter.brand.rawValue } public func isValid(_ string: String) -> Bool { @@ -79,6 +89,13 @@ public final class CreditCardFormatter { let formatter = selectFormatter(from: strippedString) return formatter.isValid(strippedString) } + + public func cvvCodeLength(from string: String) -> Int { + let strippedString = removeNonDecimalDigits(from: string) + let matchedFormatter = selectFormatter(from: strippedString) + let cvvLength = matchedFormatter.cvvLength + return cvvLength + } } extension String { diff --git a/Sources/CreditCardFormatter/Formats/AmericanExpressCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/AmericanExpressCreditCardFormat.swift index 79c749b..5c6fdee 100644 --- a/Sources/CreditCardFormatter/Formats/AmericanExpressCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/AmericanExpressCreditCardFormat.swift @@ -26,13 +26,10 @@ import Foundation -public extension CreditCardBrands { - static let americanExpress = "American Express" -} - public struct AmericanExpressCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 6, 5] - public let brand: String = CreditCardBrands.americanExpress + public let brand: CreditCardBrand = .americanExpress + public let cvvLength: Int = 4 public init() {} diff --git a/Sources/CreditCardFormatter/Formats/ChinaUnionPayCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/ChinaUnionPayCreditCardFormat.swift index 2608797..c70bbf4 100644 --- a/Sources/CreditCardFormatter/Formats/ChinaUnionPayCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/ChinaUnionPayCreditCardFormat.swift @@ -26,14 +26,11 @@ import Foundation -public extension CreditCardBrands { - static let chinaUnionPay = "China UnionPay" -} - public struct ChinaUnionPayCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 4, 4, 4] - public let brand: String = CreditCardBrands.chinaUnionPay - + public let brand: CreditCardBrand = .chinaUnionPay + public let cvvLength: Int = 3 + private let maxLength = 19 private let minLength = 13 diff --git a/Sources/CreditCardFormatter/Formats/CreditCardBrand.swift b/Sources/CreditCardFormatter/Formats/CreditCardBrand.swift new file mode 100644 index 0000000..b96d11c --- /dev/null +++ b/Sources/CreditCardFormatter/Formats/CreditCardBrand.swift @@ -0,0 +1,20 @@ +// +// CreditCardBrands.swift +// CreditCardFormatter +// +// Created by Egehan Kalayci (Dogus Teknoloji) on 13.11.2024. +// Copyright © 2024 Barbarity Apps. All rights reserved. +// + +import Foundation + +public enum CreditCardBrand: String { + case americanExpress = "American Express" + case chinaUnionPay = "China UnionPay" + case dinersClubInternational = "Diners Club International" + case discover = "Discover" + case jcb = "JCB" + case masterCard = "MasterCard" + case visa = "Visa" + case unknown = "Unknown" +} diff --git a/Sources/CreditCardFormatter/Formats/DinersClubInternationalCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/DinersClubInternationalCreditCardFormat.swift index b745bdc..200f009 100644 --- a/Sources/CreditCardFormatter/Formats/DinersClubInternationalCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/DinersClubInternationalCreditCardFormat.swift @@ -26,13 +26,10 @@ import Foundation -public extension CreditCardBrands { - static let dinersClubInternational = "Diners Club International" -} - public struct DinersClubInternationalCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 6, 4] - public let brand: String = CreditCardBrands.dinersClubInternational + public let brand: CreditCardBrand = .dinersClubInternational + public let cvvLength: Int = 3 private let maxLength = 19 private let minLength = 14 diff --git a/Sources/CreditCardFormatter/Formats/DiscoverCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/DiscoverCreditCardFormat.swift index 36eb594..38da809 100644 --- a/Sources/CreditCardFormatter/Formats/DiscoverCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/DiscoverCreditCardFormat.swift @@ -26,13 +26,10 @@ import Foundation -public extension CreditCardBrands { - static let discover = "Discover" -} - public struct DiscoverCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 4, 4, 4, 3] - public let brand: String = CreditCardBrands.discover + public let brand: CreditCardBrand = .discover + public let cvvLength: Int = 3 private let maxLength = 19 private let minLength = 16 diff --git a/Sources/CreditCardFormatter/Formats/JCBCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/JCBCreditCardFormat.swift index 66b5b28..f7cf645 100644 --- a/Sources/CreditCardFormatter/Formats/JCBCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/JCBCreditCardFormat.swift @@ -26,13 +26,10 @@ import Foundation -public extension CreditCardBrands { - static let jcb = "JCB" -} - public struct JCBCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 4, 4, 4, 3] - public let brand: String = CreditCardBrands.jcb + public let brand: CreditCardBrand = .jcb + public let cvvLength: Int = 3 private let maxLength = 19 private let minLength = 16 diff --git a/Sources/CreditCardFormatter/Formats/MasterCardCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/MasterCardCreditCardFormat.swift index e8221db..443761f 100644 --- a/Sources/CreditCardFormatter/Formats/MasterCardCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/MasterCardCreditCardFormat.swift @@ -26,13 +26,10 @@ import Foundation -public extension CreditCardBrands { - static let masterCard = "Master Card" -} - public struct MasterCardCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 4, 4, 4] - public let brand: String = CreditCardBrands.masterCard + public let brand: CreditCardBrand = .masterCard + public let cvvLength: Int = 3 public init() {} diff --git a/Sources/CreditCardFormatter/Formats/UnknownCreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/UnknownCreditCardFormat.swift index b46ef98..e2b9208 100644 --- a/Sources/CreditCardFormatter/Formats/UnknownCreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/UnknownCreditCardFormat.swift @@ -26,14 +26,11 @@ import Foundation -public enum CreditCardBrands { - public static let unknown = "Unknown" -} - struct UnknownCreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4] - public let brand: String = CreditCardBrands.unknown - + public let brand: CreditCardBrand = .unknown + public let cvvLength: Int = 4 + public init() {} public func shouldFormat(_ string: String) -> Bool { diff --git a/Sources/CreditCardFormatter/Formats/VISACreditCardFormat.swift b/Sources/CreditCardFormatter/Formats/VISACreditCardFormat.swift index 6af825d..c0d3a7a 100644 --- a/Sources/CreditCardFormatter/Formats/VISACreditCardFormat.swift +++ b/Sources/CreditCardFormatter/Formats/VISACreditCardFormat.swift @@ -26,14 +26,11 @@ import Foundation -public extension CreditCardBrands { - static let visa = "VISA" -} - public struct VISACreditCardFormat: CreditCardFormat { public let blocks: [Int] = [4, 4, 4, 4] - public let brand: String = CreditCardBrands.visa - + public let brand: CreditCardBrand = .visa + public let cvvLength: Int = 3 + public init() {} public func shouldFormat(_ string: String) -> Bool {