// // QRKeyScanner.swift // pass // // Created by Danny Moesch on 19.08.20. // Copyright © 2020 Bob Sun. All rights reserved. // struct QRKeyScanner { enum Result: Equatable { case lookingForStart case wrongKeyType(ScannableKeyType) case completed case scanned(Int) var message: String { switch self { case .lookingForStart: return "LookingForStartingFrame.".localize() case let .wrongKeyType(keyType): return "Scan\(keyType.visibility)Key.".localize() case .completed: return "Done".localize() case let .scanned(count): return "ScannedQrCodes(%d)".localize(count) } } var unrolled: (accepted: Bool, message: String) { if self == .completed { return (true, message) } return (false, message) } } private var segments = [String]() private var previousResult = Result.lookingForStart let keyType: ScannableKeyType init(keyType: ScannableKeyType) { self.keyType = keyType } var scannedKey: String { segments.joined() } mutating func add(segment: String) -> Result { // Skip duplicated segments. guard segment != segments.last else { return previousResult } // Check whether we have found the first block. guard !segments.isEmpty || segment.contains(keyType.headerStart) else { // Check whether we are scanning the wrong key type. if let counterKeyType = keyType.counterType, segment.contains(counterKeyType.headerStart) { previousResult = .wrongKeyType(counterKeyType) } return previousResult } // Update the list of scanned segments and return. segments.append(segment) if scannedKey.contains(keyType.footerStart), scannedKey.trimmed.hasSuffix(keyType.footerEnd) { return .completed } previousResult = .scanned(segments.count) return previousResult } }