1- use core:: iter:: FusedIterator ;
1+ use core:: { iter:: FusedIterator , marker :: PhantomData } ;
22
33use tinyvec:: ArrayVec ;
44
@@ -42,17 +42,27 @@ impl JamoKind {
4242}
4343}
4444
45- /// Iterator over a string's characters, with '\u{115F}' and '\u{1160}' inserted
46- /// where needed to ensure all Korean syllable blocks are in standard form
47- /// by [UAX29 rules](https://www.unicode.org/reports/tr29/#Standard_Korean_Syllables).
45+ trait NormalizeKoreanSyllables {
46+ fn insert_fillers (
47+ next_c : Option < char > ,
48+ prev_end_jamo_kind : Option < JamoKind > ,
49+ next_start_jamo_kind : Option < JamoKind > ,
50+ buf : & mut ArrayVec < [ Option < char > ; 3 ] > ,
51+ ) ->Option < char > ;
52+ }
53+
54+ // Used to abstract over UAX29 and KS X 1026-1 rules
4855#[ derive( Clone , Debug ) ]
49- pub struct StandardKoreanSyllables < I > {
56+ struct StandardizeKoreanSyllablesInner < I , N > {
5057prev_end_jamo_kind : Option < JamoKind > ,
5158buf : ArrayVec < [ Option < char > ; 3 ] > ,
5259inner : I ,
60+ normalizer : PhantomData < N > ,
5361}
5462
55- impl < I : Iterator < Item =char > > Iterator for StandardKoreanSyllables < I > {
63+ impl < I : Iterator < Item =char > , N : NormalizeKoreanSyllables > Iterator
64+ for StandardizeKoreanSyllablesInner < I , N >
65+ {
5666type Item =char ;
5767
5868fn next ( & mut self ) ->Option < Self :: Item > {
@@ -65,7 +75,7 @@ impl<I: Iterator<Item = char>> Iterator for StandardKoreanSyllables<I> {
6575 next_c. map_or ( ( None , None ) , JamoKind :: of) ;
6676self . prev_end_jamo_kind = next_end_jamo_kind;
6777
68- insert_fillers (
78+ N :: insert_fillers (
6979 next_c,
7080 prev_end_jamo_kind,
7181 next_start_jamo_kind,
@@ -87,50 +97,167 @@ impl<I: Iterator<Item = char>> Iterator for StandardKoreanSyllables<I> {
8797}
8898}
8999
90- impl < I : Iterator < Item =char > +FusedIterator > FusedIterator for StandardKoreanSyllables < I > { }
100+ impl < I : Iterator < Item =char > +FusedIterator , N : NormalizeKoreanSyllables > FusedIterator
101+ for StandardizeKoreanSyllablesInner < I , N >
102+ {
103+ }
91104
92- #[ inline]
93- fn insert_fillers (
94- next_c : Option < char > ,
95- prev_end_jamo_kind : Option < JamoKind > ,
96- next_start_jamo_kind : Option < JamoKind > ,
97- buf : & mut ArrayVec < [ Option < char > ; 3 ] > ,
98- ) ->Option < char > {
99- match ( prev_end_jamo_kind, next_start_jamo_kind) {
100- // Insert choseong filler before V not preceded by L or V
101- ( None |Some ( JamoKind :: T ) , Some ( JamoKind :: V ) ) =>{
102- buf. push ( next_c) ;
103- Some ( '\u{115F}' )
104- }
105- // Insert choseong and jungseong fillers before T preceded non-jamo
106- ( None , Some ( JamoKind :: T ) ) =>{
107- buf. push ( next_c) ;
108- buf. push ( Some ( '\u{1160}' ) ) ;
109- Some ( '\u{115F}' )
110- }
111- // Insert V filler between L and non-jamo
112- ( Some ( JamoKind :: L ) , None ) =>{
113- buf. push ( next_c) ;
114- Some ( '\u{1160}' )
105+ impl < I , N > StandardizeKoreanSyllablesInner < I , N > {
106+ #[ inline]
107+ fn new ( iter : I ) ->Self {
108+ Self {
109+ prev_end_jamo_kind : None ,
110+ buf : ArrayVec :: new ( ) ,
111+ inner : iter,
112+ normalizer : PhantomData ,
115113}
116- // For L followed by T, insert V filler, L filler, then another V filler
117- ( Some ( JamoKind :: L ) , Some ( JamoKind :: T ) ) =>{
118- buf. push ( next_c) ;
119- buf. push ( Some ( '\u{1160}' ) ) ;
120- buf. push ( Some ( '\u{115F}' ) ) ;
121- Some ( '\u{1160}' )
114+ }
115+ }
116+
117+ // UAX 29 normalization
118+
119+ #[ derive( Clone , Debug ) ]
120+ struct Uax29 ;
121+
122+ impl NormalizeKoreanSyllables for Uax29 {
123+ #[ inline]
124+ fn insert_fillers (
125+ next_c : Option < char > ,
126+ prev_end_jamo_kind : Option < JamoKind > ,
127+ next_start_jamo_kind : Option < JamoKind > ,
128+ buf : & mut ArrayVec < [ Option < char > ; 3 ] > ,
129+ ) ->Option < char > {
130+ match ( prev_end_jamo_kind, next_start_jamo_kind) {
131+ // Insert choseong filler before V not preceded by L or V
132+ ( None |Some ( JamoKind :: T ) , Some ( JamoKind :: V ) ) =>{
133+ buf. push ( next_c) ;
134+ Some ( '\u{115F}' )
135+ }
136+ // Insert choseong and jungseong fillers before T preceded non-jamo
137+ ( None , Some ( JamoKind :: T ) ) =>{
138+ buf. push ( next_c) ;
139+ buf. push ( Some ( '\u{1160}' ) ) ;
140+ Some ( '\u{115F}' )
141+ }
142+ // Insert V filler between L and non-jamo
143+ ( Some ( JamoKind :: L ) , None ) =>{
144+ buf. push ( next_c) ;
145+ Some ( '\u{1160}' )
146+ }
147+ // For L followed by T, insert V filler, L filler, then another V filler
148+ ( Some ( JamoKind :: L ) , Some ( JamoKind :: T ) ) =>{
149+ buf. push ( next_c) ;
150+ buf. push ( Some ( '\u{1160}' ) ) ;
151+ buf. push ( Some ( '\u{115F}' ) ) ;
152+ Some ( '\u{1160}' )
153+ }
154+ _ => next_c,
122155}
123- _ => next_c,
124156}
125157}
126158
127- impl < I > StandardKoreanSyllables < I > {
159+ /// Iterator over a string's characters, with U+115F and U+1160 inserted
160+ /// where needed to ensure all Korean syllable blocks are in standard form
161+ /// by [UAX29 rules](https://www.unicode.org/reports/tr29/#Standard_Korean_Syllables).
162+ #[ derive( Clone , Debug ) ]
163+ pub struct StandardizeKoreanSyllables < I > ( StandardizeKoreanSyllablesInner < I , Uax29 > ) ;
164+
165+ impl < I > StandardizeKoreanSyllables < I > {
128166#[ inline]
129167pub ( crate ) fn new ( iter : I ) ->Self {
130- Self {
131- prev_end_jamo_kind : None ,
132- buf : ArrayVec :: new ( ) ,
133- inner : iter,
168+ Self ( StandardizeKoreanSyllablesInner :: new ( iter) )
169+ }
170+ }
171+
172+ impl < I : Iterator < Item =char > > Iterator for StandardizeKoreanSyllables < I > {
173+ type Item =char ;
174+
175+ fn next ( & mut self ) ->Option < Self :: Item > {
176+ self . 0 . next ( )
177+ }
178+
179+ fn size_hint ( & self ) ->( usize , Option < usize > ) {
180+ self . 0 . size_hint ( )
181+ }
182+ }
183+
184+ impl < I : Iterator < Item =char > +FusedIterator > FusedIterator for StandardizeKoreanSyllables < I > { }
185+
186+ // KS X 1026 1 normalization
187+
188+ #[ cfg( feature ="ks_x_1026-1" ) ]
189+ #[ derive( Clone , Debug ) ]
190+ struct KsX1026_1 ;
191+
192+ #[ cfg( feature ="ks_x_1026-1" ) ]
193+ impl NormalizeKoreanSyllables for KsX1026_1 {
194+ #[ inline]
195+ fn insert_fillers (
196+ next_c : Option < char > ,
197+ prev_end_jamo_kind : Option < JamoKind > ,
198+ next_start_jamo_kind : Option < JamoKind > ,
199+ buf : & mut ArrayVec < [ Option < char > ; 3 ] > ,
200+ ) ->Option < char > {
201+ match ( prev_end_jamo_kind, next_start_jamo_kind) {
202+ // Insert choseong filler before V preceded by V, T or non-jamo
203+ ( None |Some ( JamoKind :: V |JamoKind :: T ) , Some ( JamoKind :: V ) ) =>{
204+ buf. push ( next_c) ;
205+ Some ( '\u{115F}' )
206+ }
207+ // Insert choseong and jungseong fillers before T preceded by T or non-jamo
208+ ( None |Some ( JamoKind :: T ) , Some ( JamoKind :: T ) ) =>{
209+ buf. push ( next_c) ;
210+ buf. push ( Some ( '\u{1160}' ) ) ;
211+ Some ( '\u{115F}' )
212+ }
213+ // Insert V filler between L and non-jamo or other L
214+ ( Some ( JamoKind :: L ) , None |Some ( JamoKind :: L ) ) =>{
215+ buf. push ( next_c) ;
216+ Some ( '\u{1160}' )
217+ }
218+ // For L followed by T, insert V filler, L filler, then another V filler
219+ ( Some ( JamoKind :: L ) , Some ( JamoKind :: T ) ) =>{
220+ buf. push ( next_c) ;
221+ buf. push ( Some ( '\u{1160}' ) ) ;
222+ buf. push ( Some ( '\u{115F}' ) ) ;
223+ Some ( '\u{1160}' )
224+ }
225+ _ => next_c,
134226}
135227}
136228}
229+
230+ /// Iterator over a string's characters, with U+115F and U+1160 inserted
231+ /// where needed to ensure all Korean syllable blocks are in standard form
232+ /// by [KS X 1026-1](http://std.dkuug.dk/jtc1/sc2/wg2/docs/n3422.pdf) rules.
233+ #[ cfg( feature ="ks_x_1026-1" ) ]
234+ #[ cfg_attr( docsrs, doc( cfg( feature ="ks_x_1026-1" ) ) ) ]
235+ #[ derive( Clone , Debug ) ]
236+ pub struct StandardizeKoreanSyllablesKsX1026_1 < I > ( StandardizeKoreanSyllablesInner < I , KsX1026_1 > ) ;
237+
238+ #[ cfg( feature ="ks_x_1026-1" ) ]
239+ impl < I > StandardizeKoreanSyllablesKsX1026_1 < I > {
240+ #[ inline]
241+ pub ( crate ) fn new ( iter : I ) ->Self {
242+ Self ( StandardizeKoreanSyllablesInner :: new ( iter) )
243+ }
244+ }
245+
246+ #[ cfg( feature ="ks_x_1026-1" ) ]
247+ impl < I : Iterator < Item =char > > Iterator for StandardizeKoreanSyllablesKsX1026_1 < I > {
248+ type Item =char ;
249+
250+ fn next ( & mut self ) ->Option < Self :: Item > {
251+ self . 0 . next ( )
252+ }
253+
254+ fn size_hint ( & self ) ->( usize , Option < usize > ) {
255+ self . 0 . size_hint ( )
256+ }
257+ }
258+
259+ #[ cfg( feature ="ks_x_1026-1" ) ]
260+ impl < I : Iterator < Item =char > +FusedIterator > FusedIterator
261+ for StandardizeKoreanSyllablesKsX1026_1 < I >
262+ {
263+ }