//===----------------------------------------------------------------------===// // // This source file is part of the Swift.org open source project // // Copyright (c) 2020 Apple Inc. and the Swift project authors // Licensed under Apache License v2.0 with Runtime Library Exception // // See https://swift.org/LICENSE.txt for license information // See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors // //===----------------------------------------------------------------------===// #if canImport(FoundationEssentials) import FoundationEssentials #endif @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) public struct IntegerParseStrategy : Codable, Hashable where Format : FormatStyle, Format.FormatInput : BinaryInteger { public var formatStyle: Format public var lenient: Bool } @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) extension IntegerParseStrategy : Sendable where Format : Sendable {} @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) extension IntegerParseStrategy: ParseStrategy { public func parse(_ value: String) throws -> Format.FormatInput { let trimmedString = value._trimmingWhitespace() guard let result = try parse(trimmedString, startingAt: trimmedString.startIndex, in: trimmedString.startIndex..) throws -> (String.Index, Format.FormatInput)? { guard index < range.upperBound else { return nil } let numberFormatType: ICULegacyNumberFormatter.NumberFormatType let locale: Locale if let format = formatStyle as? IntegerFormatStyle { numberFormatType = .number(format.collection) locale = format.locale } else if let format = formatStyle as? IntegerFormatStyle.Percent { numberFormatType = .percent(format.collection) locale = format.locale } else if let format = formatStyle as? IntegerFormatStyle.Currency { numberFormatType = .currency(format.collection, currencyCode: format.currencyCode) locale = format.locale } else { // For some reason we've managed to accept a format style of a type that we don't own, which shouldn't happen. Fallback to the default decimal style and try anyways. numberFormatType = .number(.init()) locale = .autoupdatingCurrent } guard let parser = ICULegacyNumberFormatter.formatter(for: numberFormatType, locale: locale, lenient: lenient) else { return nil } let substr = value[index..(format: Format, lenient: Bool = true) where Format == IntegerFormatStyle { self.formatStyle = format self.lenient = lenient } } @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) public extension IntegerParseStrategy { init(format: Format, lenient: Bool = true) where Format == IntegerFormatStyle.Percent { self.formatStyle = format self.lenient = lenient } } @available(macOS 12.0, iOS 15.0, tvOS 15.0, watchOS 8.0, *) public extension IntegerParseStrategy { init(format: Format, lenient: Bool = true) where Format == IntegerFormatStyle.Currency { self.formatStyle = format self.lenient = lenient } }