@@ -45,7 +45,7 @@ import Foundation
4545 //=--------------------------------------=
4646 formatter. numberStyle = . currency
4747 self . preferences = Preferences ( formatter)
48- self . instruction = Instruction ( id , lexicon)
48+ self . instruction = Instruction ( formatter , lexicon)
4949 }
5050
5151 //=------------------------------------------------------------------------=
@@ -108,68 +108,55 @@ import Foundation
108108 ///
109109 /// Characters used to express currencies are usually disjoint
110110 /// from characters used to express amounts, but sometimes they overlap.
111- /// This instruction is used to efficiently mark faux fraction separators, when they exist .
111+ /// This instruction is used to efficiently mark currency labels when needed .
112112 ///
113113 @usableFromInline struct Instruction {
114114
115115 //=--------------------------------------------------------------------=
116116 // MARK: State
117117 //=--------------------------------------------------------------------=
118118
119- @usableFromInline let occurances : Int
120- @usableFromInline let character : Character
119+ @usableFromInline let label : String
121120 @usableFromInline let direction : Direction
122121
123122 //=--------------------------------------------------------------------=
124123 // MARK: Initializers
125124 //=--------------------------------------------------------------------=
126125
127- @inlinable init ? < S> ( _ label: S , _ character: Character ,
128- _ direction: Direction ) where S: Sequence , S. Element == Character {
129- self . occurances = label. count ( where: { $0 == character } )
130- //=--------------------------------------=
131- // MARK: Validate
132- //=--------------------------------------=
133- guard occurances > 0 else { return nil }
134- //=--------------------------------------=
135- // MARK: Instantiate
136- //=--------------------------------------=
137- self . character = character
138- self . direction = direction
139- }
140-
141- @inlinable init ? ( _ id: ID , _ lexicon: Lexicon ) {
142- let separator = lexicon. separators [ . fraction]
143- let labels = IntegerFormatStyle < Int >
144- . Currency ( code: id. code, locale: id. locale)
145- . precision ( . fractionLength( 0 ) ) . format ( 0 ) . split (
146- separator: lexicon. digits [ . zero] ,
147- omittingEmptySubsequences: false )
126+ /// Requires that formatter.numberStyle == .currency
127+ ///
128+ /// Correctness is assert by tests parsing currency formats for all locale-currency pairs.
129+ ///
130+ @inlinable init ? ( _ formatter: NumberFormatter , _ lexicon: Lexicon ) {
131+ self . label = formatter. currencySymbol
132+ //=----------------------------------=
133+ // MARK: Check Instruction Is Needed
134+ //=----------------------------------=
135+ guard label. contains ( lexicon. separators [ . fraction] ) else { return nil }
136+ //=----------------------------------=
137+ // MARK: Formatted
148138 //=----------------------------------=
149- // MARK: Instantiate
139+ let sides = IntegerFormatStyle < Int >
140+ . Currency ( code: formatter. currencyCode, locale: formatter. locale)
141+ . precision ( . fractionLength( 0 ) ) . format ( 0 )
142+ . split ( separator: lexicon. digits [ . zero] , omittingEmptySubsequences: false )
150143 //=----------------------------------=
151- if let instance = Self ( labels [ 0 ] , separator, . forwards) { self = instance }
152- else if let instance = Self ( labels [ 1 ] , separator, . backwards) { self = instance }
153- else { return nil }
144+ // MARK: Direction
145+ //=----------------------------------=
146+ if sides [ 0 ] . contains ( label) {
147+ self . direction = . forwards
148+ } else {
149+ self . direction = . backwards; assert ( sides [ 1 ] . contains ( label) )
150+ }
154151 }
155152
156153 //=------------------------------------------------------------------------=
157154 // MARK: Utilities
158155 //=------------------------------------------------------------------------=
159156
160157 @inlinable func autocorrect( _ snapshot: inout Snapshot ) {
161- switch direction {
162- case . forwards: autocorrect ( & snapshot, indices: snapshot. indices)
163- case . backwards: autocorrect ( & snapshot, indices: snapshot. indices. reversed ( ) )
164- }
165- }
166-
167- @inlinable func autocorrect< S> ( _ snapshot: inout Snapshot ,
168- indices: S ) where S: Sequence , S. Element == Snapshot . Index {
169- var count = 0 ; for index in indices where
170- snapshot [ index] . character == character {
171- snapshot. update ( attributes: index) { $0 = . phantom }
172- count += 1 ; guard count < occurances else { return }
158+ if let range = Search . range ( of: label, in: snapshot, direction: direction) {
159+ snapshot. update ( attributes: range) { attribute in attribute = . phantom }
173160 }
174161 }
175162 }
0 commit comments