Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CreditCardFormatter.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down Expand Up @@ -74,6 +75,7 @@
65DE265F23A2FD8700916E9C /* DinersClubInternationalCreditCardFormat.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DinersClubInternationalCreditCardFormat.swift; sourceTree = "<group>"; };
65DE266123A533B300916E9C /* DinersClubInternationalCreditCardFormatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DinersClubInternationalCreditCardFormatTests.swift; sourceTree = "<group>"; };
65DE34122351018400B9F313 /* UnknownCreditCardFormatTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnknownCreditCardFormatTests.swift; sourceTree = "<group>"; };
876A747F2CE536A200B7BB5D /* CreditCardBrand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreditCardBrand.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -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 = "<group>";
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion Sources/CreditCardFormatter/CreditCardFormat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
Expand Down
19 changes: 18 additions & 1 deletion Sources/CreditCardFormatter/CreditCardFormatter.swift
Original file line number Diff line number Diff line change
Expand Up @@ -68,17 +68,34 @@ 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 {
let strippedString = removeNonDecimalDigits(from: string)
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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
20 changes: 20 additions & 0 deletions Sources/CreditCardFormatter/Formats/CreditCardBrand.swift
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
7 changes: 2 additions & 5 deletions Sources/CreditCardFormatter/Formats/JCBCreditCardFormat.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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() {}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down