unicode_matching/
lib.rs

1#![doc = include_str!("../README.md")]
2
3use gstring::{GString, GStringTrait, Grapheme};
4
5use std::collections::BTreeMap;
6
7/// Matching open/close brackets from `UnicodeData.txt`
8#[allow(clippy::unicode_not_nfc)]
9pub const MATCHING: &[(&str, &str)] = &[
10    ("(", ")"),
11    ("[", "]"),
12    ("{", "}"),
13    ("«", "»"),
14    ("‘", "’"),
15    ("“", "”"),
16    ("‹", "›"),
17    ("⁅", "⁆"),
18    ("⁽", "⁾"),
19    ("₍", "₎"),
20    ("⌈", "⌉"),
21    ("⌊", "⌋"),
22    ("〈", "〉"),
23    ("❨", "❩"),
24    ("❪", "❫"),
25    ("❬", "❭"),
26    ("❮", "❯"),
27    ("❰", "❱"),
28    ("❲", "❳"),
29    ("❴", "❵"),
30    ("⟅", "⟆"),
31    ("⟦", "⟧"),
32    ("⟨", "⟩"),
33    ("⟪", "⟫"),
34    ("⟬", "⟭"),
35    ("⟮", "⟯"),
36    ("⦃", "⦄"),
37    ("⦅", "⦆"),
38    ("⦇", "⦈"),
39    ("⦉", "⦊"),
40    ("⦋", "⦌"),
41    ("⦍", "⦎"),
42    ("⦏", "⦐"),
43    ("⦑", "⦒"),
44    ("⦓", "⦔"),
45    ("⦕", "⦖"),
46    ("⦗", "⦘"),
47    ("⧘", "⧙"),
48    ("⧚", "⧛"),
49    ("⧼", "⧽"),
50    ("⸂", "⸃"),
51    ("⸄", "⸅"),
52    ("⸉", "⸊"),
53    ("⸌", "⸍"),
54    ("⸜", "⸝"),
55    ("⸠", "⸡"),
56    ("⸢", "⸣"),
57    ("⸤", "⸥"),
58    ("⸦", "⸧"),
59    ("⸨", "⸩"),
60    ("⹕", "⹖"),
61    ("⹗", "⹘"),
62    ("⹙", "⹚"),
63    ("⹛", "⹜"),
64    ("〈", "〉"),
65    ("《", "》"),
66    ("「", "」"),
67    ("『", "』"),
68    ("【", "】"),
69    ("〔", "〕"),
70    ("〖", "〗"),
71    ("〘", "〙"),
72    ("〚", "〛"),
73    ("﴾", "﴿"),
74    ("︗", "︘"),
75    ("︵", "︶"),
76    ("︷", "︸"),
77    ("︹", "︺"),
78    ("︻", "︼"),
79    ("︽", "︾"),
80    ("︿", "﹀"),
81    ("﹁", "﹂"),
82    ("﹃", "﹄"),
83    ("﹇", "﹈"),
84    ("﹙", "﹚"),
85    ("﹛", "﹜"),
86    ("﹝", "﹞"),
87    ("(", ")"),
88    ("[", "]"),
89    ("{", "}"),
90    ("⦅", "⦆"),
91    ("「", "」"),
92];
93
94/**
95Generate a [`BTreeMap`] with the matching close bracket for each open bracket in `UnicodeData.txt`
96*/
97#[must_use]
98pub fn close() -> BTreeMap<&'static str, &'static str> {
99    MATCHING.iter().copied().collect()
100}
101
102/**
103Generate a [`BTreeMap`] with the matching open bracket for each close bracket in `UnicodeData.txt`
104*/
105#[must_use]
106pub fn open() -> BTreeMap<&'static str, &'static str> {
107    MATCHING
108        .iter()
109        .copied()
110        .map(|(open, close)| (close, open))
111        .collect()
112}
113
114/**
115Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
116`UnicodeData.txt`
117*/
118#[must_use]
119pub fn matching() -> BTreeMap<&'static str, &'static str> {
120    MATCHING
121        .iter()
122        .copied()
123        .flat_map(|(open, close)| [(open, close), (close, open)])
124        .collect()
125}
126
127/// Matching open/close brackets from `BidiBrackets.txt`
128#[allow(clippy::unicode_not_nfc)]
129pub const BRACKETS: &[(&str, &str)] = &[
130    ("(", ")"),
131    ("[", "]"),
132    ("{", "}"),
133    ("༺", "༻"),
134    ("༼", "༽"),
135    ("᚛", "᚜"),
136    ("⁅", "⁆"),
137    ("⁽", "⁾"),
138    ("₍", "₎"),
139    ("⌈", "⌉"),
140    ("⌊", "⌋"),
141    ("〈", "〉"),
142    ("❨", "❩"),
143    ("❪", "❫"),
144    ("❬", "❭"),
145    ("❮", "❯"),
146    ("❰", "❱"),
147    ("❲", "❳"),
148    ("❴", "❵"),
149    ("⟅", "⟆"),
150    ("⟦", "⟧"),
151    ("⟨", "⟩"),
152    ("⟪", "⟫"),
153    ("⟬", "⟭"),
154    ("⟮", "⟯"),
155    ("⦃", "⦄"),
156    ("⦅", "⦆"),
157    ("⦇", "⦈"),
158    ("⦉", "⦊"),
159    ("⦋", "⦌"),
160    ("⦍", "⦐"),
161    ("⦏", "⦎"),
162    ("⦑", "⦒"),
163    ("⦓", "⦔"),
164    ("⦕", "⦖"),
165    ("⦗", "⦘"),
166    ("⧘", "⧙"),
167    ("⧚", "⧛"),
168    ("⧼", "⧽"),
169    ("⸢", "⸣"),
170    ("⸤", "⸥"),
171    ("⸦", "⸧"),
172    ("⸨", "⸩"),
173    ("⹕", "⹖"),
174    ("⹗", "⹘"),
175    ("⹙", "⹚"),
176    ("⹛", "⹜"),
177    ("〈", "〉"),
178    ("《", "》"),
179    ("「", "」"),
180    ("『", "』"),
181    ("【", "】"),
182    ("〔", "〕"),
183    ("〖", "〗"),
184    ("〘", "〙"),
185    ("〚", "〛"),
186    ("﹙", "﹚"),
187    ("﹛", "﹜"),
188    ("﹝", "﹞"),
189    ("(", ")"),
190    ("[", "]"),
191    ("{", "}"),
192    ("⦅", "⦆"),
193    ("「", "」"),
194];
195
196/**
197Generate a [`BTreeMap`] with the matching close bracket for each open bracket in `BidiBrackets.txt`
198*/
199#[must_use]
200pub fn close_brackets() -> BTreeMap<&'static str, &'static str> {
201    BRACKETS.iter().copied().collect()
202}
203
204/**
205Generate a [`BTreeMap`] with the matching open bracket for each close bracket in `BidiBrackets.txt`
206*/
207#[must_use]
208pub fn open_brackets() -> BTreeMap<&'static str, &'static str> {
209    BRACKETS
210        .iter()
211        .copied()
212        .map(|(open, close)| (close, open))
213        .collect()
214}
215
216/**
217Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
218`BidiBrackets.txt`
219*/
220#[must_use]
221pub fn matching_brackets() -> BTreeMap<&'static str, &'static str> {
222    BRACKETS
223        .iter()
224        .copied()
225        .flat_map(|(open, close)| [(open, close), (close, open)])
226        .collect()
227}
228
229/// Matching open/close brackets from `BidiMirroring.txt`
230#[allow(clippy::unicode_not_nfc)]
231pub const MIRRORING: &[(&str, &str)] = &[
232    ("(", ")"),
233    ("<", ">"),
234    ("[", "]"),
235    ("{", "}"),
236    ("«", "»"),
237    ("༺", "༻"),
238    ("༼", "༽"),
239    ("᚛", "᚜"),
240    ("‹", "›"),
241    ("⁅", "⁆"),
242    ("⁽", "⁾"),
243    ("₍", "₎"),
244    ("∈", "∋"),
245    ("∉", "∌"),
246    ("∊", "∍"),
247    ("∕", "⧵"),
248    ("∟", "⯾"),
249    ("∠", "⦣"),
250    ("∡", "⦛"),
251    ("∢", "⦠"),
252    ("∤", "⫮"),
253    ("∼", "∽"),
254    ("≃", "⋍"),
255    ("≅", "≌"),
256    ("≒", "≓"),
257    ("≔", "≕"),
258    ("≤", "≥"),
259    ("≦", "≧"),
260    ("≨", "≩"),
261    ("≪", "≫"),
262    ("≮", "≯"),
263    ("≰", "≱"),
264    ("≲", "≳"),
265    ("≴", "≵"),
266    ("≶", "≷"),
267    ("≸", "≹"),
268    ("≺", "≻"),
269    ("≼", "≽"),
270    ("≾", "≿"),
271    ("⊀", "⊁"),
272    ("⊂", "⊃"),
273    ("⊄", "⊅"),
274    ("⊆", "⊇"),
275    ("⊈", "⊉"),
276    ("⊊", "⊋"),
277    ("⊏", "⊐"),
278    ("⊑", "⊒"),
279    ("⊘", "⦸"),
280    ("⊢", "⊣"),
281    ("⊦", "⫞"),
282    ("⊨", "⫤"),
283    ("⊩", "⫣"),
284    ("⊫", "⫥"),
285    ("⊰", "⊱"),
286    ("⊲", "⊳"),
287    ("⊴", "⊵"),
288    ("⊶", "⊷"),
289    ("⊸", "⟜"),
290    ("⋉", "⋊"),
291    ("⋋", "⋌"),
292    ("⋐", "⋑"),
293    ("⋖", "⋗"),
294    ("⋘", "⋙"),
295    ("⋚", "⋛"),
296    ("⋜", "⋝"),
297    ("⋞", "⋟"),
298    ("⋠", "⋡"),
299    ("⋢", "⋣"),
300    ("⋤", "⋥"),
301    ("⋦", "⋧"),
302    ("⋨", "⋩"),
303    ("⋪", "⋫"),
304    ("⋬", "⋭"),
305    ("⋰", "⋱"),
306    ("⋲", "⋺"),
307    ("⋳", "⋻"),
308    ("⋴", "⋼"),
309    ("⋶", "⋽"),
310    ("⋷", "⋾"),
311    ("⌈", "⌉"),
312    ("⌊", "⌋"),
313    ("〈", "〉"),
314    ("❨", "❩"),
315    ("❪", "❫"),
316    ("❬", "❭"),
317    ("❮", "❯"),
318    ("❰", "❱"),
319    ("❲", "❳"),
320    ("❴", "❵"),
321    ("⟃", "⟄"),
322    ("⟅", "⟆"),
323    ("⟈", "⟉"),
324    ("⟋", "⟍"),
325    ("⟕", "⟖"),
326    ("⟝", "⟞"),
327    ("⟢", "⟣"),
328    ("⟤", "⟥"),
329    ("⟦", "⟧"),
330    ("⟨", "⟩"),
331    ("⟪", "⟫"),
332    ("⟬", "⟭"),
333    ("⟮", "⟯"),
334    ("⦃", "⦄"),
335    ("⦅", "⦆"),
336    ("⦇", "⦈"),
337    ("⦉", "⦊"),
338    ("⦋", "⦌"),
339    ("⦍", "⦐"),
340    ("⦎", "⦏"),
341    ("⦑", "⦒"),
342    ("⦓", "⦔"),
343    ("⦕", "⦖"),
344    ("⦗", "⦘"),
345    ("⦤", "⦥"),
346    ("⦨", "⦩"),
347    ("⦪", "⦫"),
348    ("⦬", "⦭"),
349    ("⦮", "⦯"),
350    ("⧀", "⧁"),
351    ("⧄", "⧅"),
352    ("⧏", "⧐"),
353    ("⧑", "⧒"),
354    ("⧔", "⧕"),
355    ("⧘", "⧙"),
356    ("⧚", "⧛"),
357    ("⧨", "⧩"),
358    ("⧸", "⧹"),
359    ("⧼", "⧽"),
360    ("⨫", "⨬"),
361    ("⨭", "⨮"),
362    ("⨴", "⨵"),
363    ("⨼", "⨽"),
364    ("⩤", "⩥"),
365    ("⩹", "⩺"),
366    ("⩻", "⩼"),
367    ("⩽", "⩾"),
368    ("⩿", "⪀"),
369    ("⪁", "⪂"),
370    ("⪃", "⪄"),
371    ("⪅", "⪆"),
372    ("⪇", "⪈"),
373    ("⪉", "⪊"),
374    ("⪋", "⪌"),
375    ("⪍", "⪎"),
376    ("⪏", "⪐"),
377    ("⪑", "⪒"),
378    ("⪓", "⪔"),
379    ("⪕", "⪖"),
380    ("⪗", "⪘"),
381    ("⪙", "⪚"),
382    ("⪛", "⪜"),
383    ("⪝", "⪞"),
384    ("⪟", "⪠"),
385    ("⪡", "⪢"),
386    ("⪦", "⪧"),
387    ("⪨", "⪩"),
388    ("⪪", "⪫"),
389    ("⪬", "⪭"),
390    ("⪯", "⪰"),
391    ("⪱", "⪲"),
392    ("⪳", "⪴"),
393    ("⪵", "⪶"),
394    ("⪷", "⪸"),
395    ("⪹", "⪺"),
396    ("⪻", "⪼"),
397    ("⪽", "⪾"),
398    ("⪿", "⫀"),
399    ("⫁", "⫂"),
400    ("⫃", "⫄"),
401    ("⫅", "⫆"),
402    ("⫇", "⫈"),
403    ("⫉", "⫊"),
404    ("⫋", "⫌"),
405    ("⫍", "⫎"),
406    ("⫏", "⫐"),
407    ("⫑", "⫒"),
408    ("⫓", "⫔"),
409    ("⫕", "⫖"),
410    ("⫬", "⫭"),
411    ("⫷", "⫸"),
412    ("⫹", "⫺"),
413    ("⸂", "⸃"),
414    ("⸄", "⸅"),
415    ("⸉", "⸊"),
416    ("⸌", "⸍"),
417    ("⸜", "⸝"),
418    ("⸠", "⸡"),
419    ("⸢", "⸣"),
420    ("⸤", "⸥"),
421    ("⸦", "⸧"),
422    ("⸨", "⸩"),
423    ("⹕", "⹖"),
424    ("⹗", "⹘"),
425    ("⹙", "⹚"),
426    ("⹛", "⹜"),
427    ("〈", "〉"),
428    ("《", "》"),
429    ("「", "」"),
430    ("『", "』"),
431    ("【", "】"),
432    ("〔", "〕"),
433    ("〖", "〗"),
434    ("〘", "〙"),
435    ("〚", "〛"),
436    ("﹙", "﹚"),
437    ("﹛", "﹜"),
438    ("﹝", "﹞"),
439    ("﹤", "﹥"),
440    ("(", ")"),
441    ("<", ">"),
442    ("[", "]"),
443    ("{", "}"),
444    ("⦅", "⦆"),
445    ("「", "」"),
446];
447
448/**
449Generate a [`BTreeMap`] with the matching close bracket for each open bracket in
450`BidiMirroring.txt`
451*/
452#[must_use]
453pub fn close_mirroring() -> BTreeMap<&'static str, &'static str> {
454    MIRRORING.iter().copied().collect()
455}
456
457/**
458Generate a [`BTreeMap`] with the matching open bracket for each close bracket in
459`BidiMirroring.txt`
460*/
461#[must_use]
462pub fn open_mirroring() -> BTreeMap<&'static str, &'static str> {
463    MIRRORING
464        .iter()
465        .copied()
466        .map(|(open, close)| (close, open))
467        .collect()
468}
469
470/**
471Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
472`BidiMirroring.txt`
473*/
474#[must_use]
475pub fn matching_mirroring() -> BTreeMap<&'static str, &'static str> {
476    MIRRORING
477        .iter()
478        .copied()
479        .flat_map(|(open, close)| [(open, close), (close, open)])
480        .collect()
481}
482
483/// Matching open/close brackets from `UnicodeData.txt` and `BidiBrackets.txt`
484#[allow(clippy::unicode_not_nfc)]
485pub const BRACKETS_MATCHING: &[(&str, &str)] = &[
486    ("(", ")"),
487    ("[", "]"),
488    ("{", "}"),
489    ("«", "»"),
490    ("༺", "༻"),
491    ("༼", "༽"),
492    ("᚛", "᚜"),
493    ("‘", "’"),
494    ("“", "”"),
495    ("‹", "›"),
496    ("⁅", "⁆"),
497    ("⁽", "⁾"),
498    ("₍", "₎"),
499    ("⌈", "⌉"),
500    ("⌊", "⌋"),
501    ("〈", "〉"),
502    ("❨", "❩"),
503    ("❪", "❫"),
504    ("❬", "❭"),
505    ("❮", "❯"),
506    ("❰", "❱"),
507    ("❲", "❳"),
508    ("❴", "❵"),
509    ("⟅", "⟆"),
510    ("⟦", "⟧"),
511    ("⟨", "⟩"),
512    ("⟪", "⟫"),
513    ("⟬", "⟭"),
514    ("⟮", "⟯"),
515    ("⦃", "⦄"),
516    ("⦅", "⦆"),
517    ("⦇", "⦈"),
518    ("⦉", "⦊"),
519    ("⦋", "⦌"),
520    ("⦍", "⦎"),
521    ("⦏", "⦐"),
522    ("⦑", "⦒"),
523    ("⦓", "⦔"),
524    ("⦕", "⦖"),
525    ("⦗", "⦘"),
526    ("⧘", "⧙"),
527    ("⧚", "⧛"),
528    ("⧼", "⧽"),
529    ("⸂", "⸃"),
530    ("⸄", "⸅"),
531    ("⸉", "⸊"),
532    ("⸌", "⸍"),
533    ("⸜", "⸝"),
534    ("⸠", "⸡"),
535    ("⸢", "⸣"),
536    ("⸤", "⸥"),
537    ("⸦", "⸧"),
538    ("⸨", "⸩"),
539    ("⹕", "⹖"),
540    ("⹗", "⹘"),
541    ("⹙", "⹚"),
542    ("⹛", "⹜"),
543    ("〈", "〉"),
544    ("《", "》"),
545    ("「", "」"),
546    ("『", "』"),
547    ("【", "】"),
548    ("〔", "〕"),
549    ("〖", "〗"),
550    ("〘", "〙"),
551    ("〚", "〛"),
552    ("﴾", "﴿"),
553    ("︗", "︘"),
554    ("︵", "︶"),
555    ("︷", "︸"),
556    ("︹", "︺"),
557    ("︻", "︼"),
558    ("︽", "︾"),
559    ("︿", "﹀"),
560    ("﹁", "﹂"),
561    ("﹃", "﹄"),
562    ("﹇", "﹈"),
563    ("﹙", "﹚"),
564    ("﹛", "﹜"),
565    ("﹝", "﹞"),
566    ("(", ")"),
567    ("[", "]"),
568    ("{", "}"),
569    ("⦅", "⦆"),
570    ("「", "」"),
571];
572
573/**
574Generate a [`BTreeMap`] with the matching close bracket for each open bracket in `UnicodeData.txt`
575and `BidiBrackets.txt`
576*/
577#[must_use]
578pub fn close_brackets_matching() -> BTreeMap<&'static str, &'static str> {
579    BRACKETS_MATCHING.iter().copied().collect()
580}
581
582/**
583Generate a [`BTreeMap`] with the matching open bracket for each close bracket in `UnicodeData.txt`
584and `BidiBrackets.txt`
585*/
586#[must_use]
587pub fn open_brackets_matching() -> BTreeMap<&'static str, &'static str> {
588    BRACKETS_MATCHING
589        .iter()
590        .copied()
591        .map(|(open, close)| (close, open))
592        .collect()
593}
594
595/**
596Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
597`UnicodeData.txt` and `BidiBrackets.txt`
598*/
599#[must_use]
600pub fn matching_brackets_matching() -> BTreeMap<&'static str, &'static str> {
601    BRACKETS_MATCHING
602        .iter()
603        .copied()
604        .flat_map(|(open, close)| [(open, close), (close, open)])
605        .collect()
606}
607
608/// Matching open/close brackets from `BidiMirroring.txt` and `BidiBrackets.txt`
609#[allow(clippy::unicode_not_nfc)]
610pub const BRACKETS_MIRRORING: &[(&str, &str)] = &[
611    ("(", ")"),
612    ("<", ">"),
613    ("[", "]"),
614    ("{", "}"),
615    ("«", "»"),
616    ("༺", "༻"),
617    ("༼", "༽"),
618    ("᚛", "᚜"),
619    ("‹", "›"),
620    ("⁅", "⁆"),
621    ("⁽", "⁾"),
622    ("₍", "₎"),
623    ("∈", "∋"),
624    ("∉", "∌"),
625    ("∊", "∍"),
626    ("∕", "⧵"),
627    ("∟", "⯾"),
628    ("∠", "⦣"),
629    ("∡", "⦛"),
630    ("∢", "⦠"),
631    ("∤", "⫮"),
632    ("∼", "∽"),
633    ("≃", "⋍"),
634    ("≅", "≌"),
635    ("≒", "≓"),
636    ("≔", "≕"),
637    ("≤", "≥"),
638    ("≦", "≧"),
639    ("≨", "≩"),
640    ("≪", "≫"),
641    ("≮", "≯"),
642    ("≰", "≱"),
643    ("≲", "≳"),
644    ("≴", "≵"),
645    ("≶", "≷"),
646    ("≸", "≹"),
647    ("≺", "≻"),
648    ("≼", "≽"),
649    ("≾", "≿"),
650    ("⊀", "⊁"),
651    ("⊂", "⊃"),
652    ("⊄", "⊅"),
653    ("⊆", "⊇"),
654    ("⊈", "⊉"),
655    ("⊊", "⊋"),
656    ("⊏", "⊐"),
657    ("⊑", "⊒"),
658    ("⊘", "⦸"),
659    ("⊢", "⊣"),
660    ("⊦", "⫞"),
661    ("⊨", "⫤"),
662    ("⊩", "⫣"),
663    ("⊫", "⫥"),
664    ("⊰", "⊱"),
665    ("⊲", "⊳"),
666    ("⊴", "⊵"),
667    ("⊶", "⊷"),
668    ("⊸", "⟜"),
669    ("⋉", "⋊"),
670    ("⋋", "⋌"),
671    ("⋐", "⋑"),
672    ("⋖", "⋗"),
673    ("⋘", "⋙"),
674    ("⋚", "⋛"),
675    ("⋜", "⋝"),
676    ("⋞", "⋟"),
677    ("⋠", "⋡"),
678    ("⋢", "⋣"),
679    ("⋤", "⋥"),
680    ("⋦", "⋧"),
681    ("⋨", "⋩"),
682    ("⋪", "⋫"),
683    ("⋬", "⋭"),
684    ("⋰", "⋱"),
685    ("⋲", "⋺"),
686    ("⋳", "⋻"),
687    ("⋴", "⋼"),
688    ("⋶", "⋽"),
689    ("⋷", "⋾"),
690    ("⌈", "⌉"),
691    ("⌊", "⌋"),
692    ("〈", "〉"),
693    ("❨", "❩"),
694    ("❪", "❫"),
695    ("❬", "❭"),
696    ("❮", "❯"),
697    ("❰", "❱"),
698    ("❲", "❳"),
699    ("❴", "❵"),
700    ("⟃", "⟄"),
701    ("⟅", "⟆"),
702    ("⟈", "⟉"),
703    ("⟋", "⟍"),
704    ("⟕", "⟖"),
705    ("⟝", "⟞"),
706    ("⟢", "⟣"),
707    ("⟤", "⟥"),
708    ("⟦", "⟧"),
709    ("⟨", "⟩"),
710    ("⟪", "⟫"),
711    ("⟬", "⟭"),
712    ("⟮", "⟯"),
713    ("⦃", "⦄"),
714    ("⦅", "⦆"),
715    ("⦇", "⦈"),
716    ("⦉", "⦊"),
717    ("⦋", "⦌"),
718    ("⦍", "⦐"),
719    ("⦎", "⦏"),
720    ("⦏", "⦎"),
721    ("⦑", "⦒"),
722    ("⦓", "⦔"),
723    ("⦕", "⦖"),
724    ("⦗", "⦘"),
725    ("⦤", "⦥"),
726    ("⦨", "⦩"),
727    ("⦪", "⦫"),
728    ("⦬", "⦭"),
729    ("⦮", "⦯"),
730    ("⧀", "⧁"),
731    ("⧄", "⧅"),
732    ("⧏", "⧐"),
733    ("⧑", "⧒"),
734    ("⧔", "⧕"),
735    ("⧘", "⧙"),
736    ("⧚", "⧛"),
737    ("⧨", "⧩"),
738    ("⧸", "⧹"),
739    ("⧼", "⧽"),
740    ("⨫", "⨬"),
741    ("⨭", "⨮"),
742    ("⨴", "⨵"),
743    ("⨼", "⨽"),
744    ("⩤", "⩥"),
745    ("⩹", "⩺"),
746    ("⩻", "⩼"),
747    ("⩽", "⩾"),
748    ("⩿", "⪀"),
749    ("⪁", "⪂"),
750    ("⪃", "⪄"),
751    ("⪅", "⪆"),
752    ("⪇", "⪈"),
753    ("⪉", "⪊"),
754    ("⪋", "⪌"),
755    ("⪍", "⪎"),
756    ("⪏", "⪐"),
757    ("⪑", "⪒"),
758    ("⪓", "⪔"),
759    ("⪕", "⪖"),
760    ("⪗", "⪘"),
761    ("⪙", "⪚"),
762    ("⪛", "⪜"),
763    ("⪝", "⪞"),
764    ("⪟", "⪠"),
765    ("⪡", "⪢"),
766    ("⪦", "⪧"),
767    ("⪨", "⪩"),
768    ("⪪", "⪫"),
769    ("⪬", "⪭"),
770    ("⪯", "⪰"),
771    ("⪱", "⪲"),
772    ("⪳", "⪴"),
773    ("⪵", "⪶"),
774    ("⪷", "⪸"),
775    ("⪹", "⪺"),
776    ("⪻", "⪼"),
777    ("⪽", "⪾"),
778    ("⪿", "⫀"),
779    ("⫁", "⫂"),
780    ("⫃", "⫄"),
781    ("⫅", "⫆"),
782    ("⫇", "⫈"),
783    ("⫉", "⫊"),
784    ("⫋", "⫌"),
785    ("⫍", "⫎"),
786    ("⫏", "⫐"),
787    ("⫑", "⫒"),
788    ("⫓", "⫔"),
789    ("⫕", "⫖"),
790    ("⫬", "⫭"),
791    ("⫷", "⫸"),
792    ("⫹", "⫺"),
793    ("⸂", "⸃"),
794    ("⸄", "⸅"),
795    ("⸉", "⸊"),
796    ("⸌", "⸍"),
797    ("⸜", "⸝"),
798    ("⸠", "⸡"),
799    ("⸢", "⸣"),
800    ("⸤", "⸥"),
801    ("⸦", "⸧"),
802    ("⸨", "⸩"),
803    ("⹕", "⹖"),
804    ("⹗", "⹘"),
805    ("⹙", "⹚"),
806    ("⹛", "⹜"),
807    ("〈", "〉"),
808    ("《", "》"),
809    ("「", "」"),
810    ("『", "』"),
811    ("【", "】"),
812    ("〔", "〕"),
813    ("〖", "〗"),
814    ("〘", "〙"),
815    ("〚", "〛"),
816    ("﹙", "﹚"),
817    ("﹛", "﹜"),
818    ("﹝", "﹞"),
819    ("﹤", "﹥"),
820    ("(", ")"),
821    ("<", ">"),
822    ("[", "]"),
823    ("{", "}"),
824    ("⦅", "⦆"),
825    ("「", "」"),
826];
827
828/**
829Generate a [`BTreeMap`] with the matching close bracket for each open bracket in
830`BidiMirroring.txt` and `BidiBrackets.txt`
831*/
832#[must_use]
833pub fn close_brackets_mirroring() -> BTreeMap<&'static str, &'static str> {
834    BRACKETS_MIRRORING.iter().copied().collect()
835}
836
837/**
838Generate a [`BTreeMap`] with the matching open bracket for each close bracket in
839`BidiMirroring.txt` and `BidiBrackets.txt`
840*/
841#[must_use]
842pub fn open_brackets_mirroring() -> BTreeMap<&'static str, &'static str> {
843    BRACKETS_MIRRORING
844        .iter()
845        .copied()
846        .map(|(open, close)| (close, open))
847        .collect()
848}
849
850/**
851Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
852`BidiMirroring.txt` and `BidiBrackets.txt`
853*/
854#[must_use]
855pub fn matching_brackets_mirroring() -> BTreeMap<&'static str, &'static str> {
856    BRACKETS_MIRRORING
857        .iter()
858        .copied()
859        .flat_map(|(open, close)| [(open, close), (close, open)])
860        .collect()
861}
862
863/// Matching open/close brackets from `UnicodeData.txt` and `BidiMirroring.txt`
864#[allow(clippy::unicode_not_nfc)]
865pub const MIRRORING_MATCHING: &[(&str, &str)] = &[
866    ("(", ")"),
867    ("<", ">"),
868    ("[", "]"),
869    ("{", "}"),
870    ("«", "»"),
871    ("༺", "༻"),
872    ("༼", "༽"),
873    ("᚛", "᚜"),
874    ("‘", "’"),
875    ("“", "”"),
876    ("‹", "›"),
877    ("⁅", "⁆"),
878    ("⁽", "⁾"),
879    ("₍", "₎"),
880    ("∈", "∋"),
881    ("∉", "∌"),
882    ("∊", "∍"),
883    ("∕", "⧵"),
884    ("∟", "⯾"),
885    ("∠", "⦣"),
886    ("∡", "⦛"),
887    ("∢", "⦠"),
888    ("∤", "⫮"),
889    ("∼", "∽"),
890    ("≃", "⋍"),
891    ("≅", "≌"),
892    ("≒", "≓"),
893    ("≔", "≕"),
894    ("≤", "≥"),
895    ("≦", "≧"),
896    ("≨", "≩"),
897    ("≪", "≫"),
898    ("≮", "≯"),
899    ("≰", "≱"),
900    ("≲", "≳"),
901    ("≴", "≵"),
902    ("≶", "≷"),
903    ("≸", "≹"),
904    ("≺", "≻"),
905    ("≼", "≽"),
906    ("≾", "≿"),
907    ("⊀", "⊁"),
908    ("⊂", "⊃"),
909    ("⊄", "⊅"),
910    ("⊆", "⊇"),
911    ("⊈", "⊉"),
912    ("⊊", "⊋"),
913    ("⊏", "⊐"),
914    ("⊑", "⊒"),
915    ("⊘", "⦸"),
916    ("⊢", "⊣"),
917    ("⊦", "⫞"),
918    ("⊨", "⫤"),
919    ("⊩", "⫣"),
920    ("⊫", "⫥"),
921    ("⊰", "⊱"),
922    ("⊲", "⊳"),
923    ("⊴", "⊵"),
924    ("⊶", "⊷"),
925    ("⊸", "⟜"),
926    ("⋉", "⋊"),
927    ("⋋", "⋌"),
928    ("⋐", "⋑"),
929    ("⋖", "⋗"),
930    ("⋘", "⋙"),
931    ("⋚", "⋛"),
932    ("⋜", "⋝"),
933    ("⋞", "⋟"),
934    ("⋠", "⋡"),
935    ("⋢", "⋣"),
936    ("⋤", "⋥"),
937    ("⋦", "⋧"),
938    ("⋨", "⋩"),
939    ("⋪", "⋫"),
940    ("⋬", "⋭"),
941    ("⋰", "⋱"),
942    ("⋲", "⋺"),
943    ("⋳", "⋻"),
944    ("⋴", "⋼"),
945    ("⋶", "⋽"),
946    ("⋷", "⋾"),
947    ("⌈", "⌉"),
948    ("⌊", "⌋"),
949    ("〈", "〉"),
950    ("❨", "❩"),
951    ("❪", "❫"),
952    ("❬", "❭"),
953    ("❮", "❯"),
954    ("❰", "❱"),
955    ("❲", "❳"),
956    ("❴", "❵"),
957    ("⟃", "⟄"),
958    ("⟅", "⟆"),
959    ("⟈", "⟉"),
960    ("⟋", "⟍"),
961    ("⟕", "⟖"),
962    ("⟝", "⟞"),
963    ("⟢", "⟣"),
964    ("⟤", "⟥"),
965    ("⟦", "⟧"),
966    ("⟨", "⟩"),
967    ("⟪", "⟫"),
968    ("⟬", "⟭"),
969    ("⟮", "⟯"),
970    ("⦃", "⦄"),
971    ("⦅", "⦆"),
972    ("⦇", "⦈"),
973    ("⦉", "⦊"),
974    ("⦋", "⦌"),
975    ("⦍", "⦎"),
976    ("⦎", "⦏"),
977    ("⦏", "⦐"),
978    ("⦑", "⦒"),
979    ("⦓", "⦔"),
980    ("⦕", "⦖"),
981    ("⦗", "⦘"),
982    ("⦤", "⦥"),
983    ("⦨", "⦩"),
984    ("⦪", "⦫"),
985    ("⦬", "⦭"),
986    ("⦮", "⦯"),
987    ("⧀", "⧁"),
988    ("⧄", "⧅"),
989    ("⧏", "⧐"),
990    ("⧑", "⧒"),
991    ("⧔", "⧕"),
992    ("⧘", "⧙"),
993    ("⧚", "⧛"),
994    ("⧨", "⧩"),
995    ("⧸", "⧹"),
996    ("⧼", "⧽"),
997    ("⨫", "⨬"),
998    ("⨭", "⨮"),
999    ("⨴", "⨵"),
1000    ("⨼", "⨽"),
1001    ("⩤", "⩥"),
1002    ("⩹", "⩺"),
1003    ("⩻", "⩼"),
1004    ("⩽", "⩾"),
1005    ("⩿", "⪀"),
1006    ("⪁", "⪂"),
1007    ("⪃", "⪄"),
1008    ("⪅", "⪆"),
1009    ("⪇", "⪈"),
1010    ("⪉", "⪊"),
1011    ("⪋", "⪌"),
1012    ("⪍", "⪎"),
1013    ("⪏", "⪐"),
1014    ("⪑", "⪒"),
1015    ("⪓", "⪔"),
1016    ("⪕", "⪖"),
1017    ("⪗", "⪘"),
1018    ("⪙", "⪚"),
1019    ("⪛", "⪜"),
1020    ("⪝", "⪞"),
1021    ("⪟", "⪠"),
1022    ("⪡", "⪢"),
1023    ("⪦", "⪧"),
1024    ("⪨", "⪩"),
1025    ("⪪", "⪫"),
1026    ("⪬", "⪭"),
1027    ("⪯", "⪰"),
1028    ("⪱", "⪲"),
1029    ("⪳", "⪴"),
1030    ("⪵", "⪶"),
1031    ("⪷", "⪸"),
1032    ("⪹", "⪺"),
1033    ("⪻", "⪼"),
1034    ("⪽", "⪾"),
1035    ("⪿", "⫀"),
1036    ("⫁", "⫂"),
1037    ("⫃", "⫄"),
1038    ("⫅", "⫆"),
1039    ("⫇", "⫈"),
1040    ("⫉", "⫊"),
1041    ("⫋", "⫌"),
1042    ("⫍", "⫎"),
1043    ("⫏", "⫐"),
1044    ("⫑", "⫒"),
1045    ("⫓", "⫔"),
1046    ("⫕", "⫖"),
1047    ("⫬", "⫭"),
1048    ("⫷", "⫸"),
1049    ("⫹", "⫺"),
1050    ("⸂", "⸃"),
1051    ("⸄", "⸅"),
1052    ("⸉", "⸊"),
1053    ("⸌", "⸍"),
1054    ("⸜", "⸝"),
1055    ("⸠", "⸡"),
1056    ("⸢", "⸣"),
1057    ("⸤", "⸥"),
1058    ("⸦", "⸧"),
1059    ("⸨", "⸩"),
1060    ("⹕", "⹖"),
1061    ("⹗", "⹘"),
1062    ("⹙", "⹚"),
1063    ("⹛", "⹜"),
1064    ("〈", "〉"),
1065    ("《", "》"),
1066    ("「", "」"),
1067    ("『", "』"),
1068    ("【", "】"),
1069    ("〔", "〕"),
1070    ("〖", "〗"),
1071    ("〘", "〙"),
1072    ("〚", "〛"),
1073    ("﴾", "﴿"),
1074    ("︗", "︘"),
1075    ("︵", "︶"),
1076    ("︷", "︸"),
1077    ("︹", "︺"),
1078    ("︻", "︼"),
1079    ("︽", "︾"),
1080    ("︿", "﹀"),
1081    ("﹁", "﹂"),
1082    ("﹃", "﹄"),
1083    ("﹇", "﹈"),
1084    ("﹙", "﹚"),
1085    ("﹛", "﹜"),
1086    ("﹝", "﹞"),
1087    ("﹤", "﹥"),
1088    ("(", ")"),
1089    ("<", ">"),
1090    ("[", "]"),
1091    ("{", "}"),
1092    ("⦅", "⦆"),
1093    ("「", "」"),
1094];
1095
1096/**
1097Generate a [`BTreeMap`] with the matching close bracket for each open bracket in `UnicodeData.txt`
1098and `BidiMirroring.txt`
1099*/
1100#[must_use]
1101pub fn close_mirroring_matching() -> BTreeMap<&'static str, &'static str> {
1102    MIRRORING_MATCHING.iter().copied().collect()
1103}
1104
1105/**
1106Generate a [`BTreeMap`] with the matching open bracket for each close bracket in `UnicodeData.txt`
1107and `BidiMirroring.txt`
1108*/
1109#[must_use]
1110pub fn open_mirroring_matching() -> BTreeMap<&'static str, &'static str> {
1111    MIRRORING_MATCHING
1112        .iter()
1113        .copied()
1114        .map(|(open, close)| (close, open))
1115        .collect()
1116}
1117
1118/**
1119Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
1120`UnicodeData.txt` and `BidiMirroring.txt`
1121*/
1122#[must_use]
1123pub fn matching_mirroring_matching() -> BTreeMap<&'static str, &'static str> {
1124    MIRRORING_MATCHING
1125        .iter()
1126        .copied()
1127        .flat_map(|(open, close)| [(open, close), (close, open)])
1128        .collect()
1129}
1130
1131/// Matching open/close brackets from `UnicodeData.txt`, `BidiBrackets.txt`, and `BidiMirroring.txt`
1132#[allow(clippy::unicode_not_nfc)]
1133pub const ALL: &[(&str, &str)] = &[
1134    ("(", ")"),
1135    ("<", ">"),
1136    ("[", "]"),
1137    ("{", "}"),
1138    ("«", "»"),
1139    ("༺", "༻"),
1140    ("༼", "༽"),
1141    ("᚛", "᚜"),
1142    ("‘", "’"),
1143    ("“", "”"),
1144    ("‹", "›"),
1145    ("⁅", "⁆"),
1146    ("⁽", "⁾"),
1147    ("₍", "₎"),
1148    ("∈", "∋"),
1149    ("∉", "∌"),
1150    ("∊", "∍"),
1151    ("∕", "⧵"),
1152    ("∟", "⯾"),
1153    ("∠", "⦣"),
1154    ("∡", "⦛"),
1155    ("∢", "⦠"),
1156    ("∤", "⫮"),
1157    ("∼", "∽"),
1158    ("≃", "⋍"),
1159    ("≅", "≌"),
1160    ("≒", "≓"),
1161    ("≔", "≕"),
1162    ("≤", "≥"),
1163    ("≦", "≧"),
1164    ("≨", "≩"),
1165    ("≪", "≫"),
1166    ("≮", "≯"),
1167    ("≰", "≱"),
1168    ("≲", "≳"),
1169    ("≴", "≵"),
1170    ("≶", "≷"),
1171    ("≸", "≹"),
1172    ("≺", "≻"),
1173    ("≼", "≽"),
1174    ("≾", "≿"),
1175    ("⊀", "⊁"),
1176    ("⊂", "⊃"),
1177    ("⊄", "⊅"),
1178    ("⊆", "⊇"),
1179    ("⊈", "⊉"),
1180    ("⊊", "⊋"),
1181    ("⊏", "⊐"),
1182    ("⊑", "⊒"),
1183    ("⊘", "⦸"),
1184    ("⊢", "⊣"),
1185    ("⊦", "⫞"),
1186    ("⊨", "⫤"),
1187    ("⊩", "⫣"),
1188    ("⊫", "⫥"),
1189    ("⊰", "⊱"),
1190    ("⊲", "⊳"),
1191    ("⊴", "⊵"),
1192    ("⊶", "⊷"),
1193    ("⊸", "⟜"),
1194    ("⋉", "⋊"),
1195    ("⋋", "⋌"),
1196    ("⋐", "⋑"),
1197    ("⋖", "⋗"),
1198    ("⋘", "⋙"),
1199    ("⋚", "⋛"),
1200    ("⋜", "⋝"),
1201    ("⋞", "⋟"),
1202    ("⋠", "⋡"),
1203    ("⋢", "⋣"),
1204    ("⋤", "⋥"),
1205    ("⋦", "⋧"),
1206    ("⋨", "⋩"),
1207    ("⋪", "⋫"),
1208    ("⋬", "⋭"),
1209    ("⋰", "⋱"),
1210    ("⋲", "⋺"),
1211    ("⋳", "⋻"),
1212    ("⋴", "⋼"),
1213    ("⋶", "⋽"),
1214    ("⋷", "⋾"),
1215    ("⌈", "⌉"),
1216    ("⌊", "⌋"),
1217    ("〈", "〉"),
1218    ("❨", "❩"),
1219    ("❪", "❫"),
1220    ("❬", "❭"),
1221    ("❮", "❯"),
1222    ("❰", "❱"),
1223    ("❲", "❳"),
1224    ("❴", "❵"),
1225    ("⟃", "⟄"),
1226    ("⟅", "⟆"),
1227    ("⟈", "⟉"),
1228    ("⟋", "⟍"),
1229    ("⟕", "⟖"),
1230    ("⟝", "⟞"),
1231    ("⟢", "⟣"),
1232    ("⟤", "⟥"),
1233    ("⟦", "⟧"),
1234    ("⟨", "⟩"),
1235    ("⟪", "⟫"),
1236    ("⟬", "⟭"),
1237    ("⟮", "⟯"),
1238    ("⦃", "⦄"),
1239    ("⦅", "⦆"),
1240    ("⦇", "⦈"),
1241    ("⦉", "⦊"),
1242    ("⦋", "⦌"),
1243    ("⦍", "⦎"),
1244    ("⦎", "⦏"),
1245    ("⦏", "⦐"),
1246    ("⦑", "⦒"),
1247    ("⦓", "⦔"),
1248    ("⦕", "⦖"),
1249    ("⦗", "⦘"),
1250    ("⦤", "⦥"),
1251    ("⦨", "⦩"),
1252    ("⦪", "⦫"),
1253    ("⦬", "⦭"),
1254    ("⦮", "⦯"),
1255    ("⧀", "⧁"),
1256    ("⧄", "⧅"),
1257    ("⧏", "⧐"),
1258    ("⧑", "⧒"),
1259    ("⧔", "⧕"),
1260    ("⧘", "⧙"),
1261    ("⧚", "⧛"),
1262    ("⧨", "⧩"),
1263    ("⧸", "⧹"),
1264    ("⧼", "⧽"),
1265    ("⨫", "⨬"),
1266    ("⨭", "⨮"),
1267    ("⨴", "⨵"),
1268    ("⨼", "⨽"),
1269    ("⩤", "⩥"),
1270    ("⩹", "⩺"),
1271    ("⩻", "⩼"),
1272    ("⩽", "⩾"),
1273    ("⩿", "⪀"),
1274    ("⪁", "⪂"),
1275    ("⪃", "⪄"),
1276    ("⪅", "⪆"),
1277    ("⪇", "⪈"),
1278    ("⪉", "⪊"),
1279    ("⪋", "⪌"),
1280    ("⪍", "⪎"),
1281    ("⪏", "⪐"),
1282    ("⪑", "⪒"),
1283    ("⪓", "⪔"),
1284    ("⪕", "⪖"),
1285    ("⪗", "⪘"),
1286    ("⪙", "⪚"),
1287    ("⪛", "⪜"),
1288    ("⪝", "⪞"),
1289    ("⪟", "⪠"),
1290    ("⪡", "⪢"),
1291    ("⪦", "⪧"),
1292    ("⪨", "⪩"),
1293    ("⪪", "⪫"),
1294    ("⪬", "⪭"),
1295    ("⪯", "⪰"),
1296    ("⪱", "⪲"),
1297    ("⪳", "⪴"),
1298    ("⪵", "⪶"),
1299    ("⪷", "⪸"),
1300    ("⪹", "⪺"),
1301    ("⪻", "⪼"),
1302    ("⪽", "⪾"),
1303    ("⪿", "⫀"),
1304    ("⫁", "⫂"),
1305    ("⫃", "⫄"),
1306    ("⫅", "⫆"),
1307    ("⫇", "⫈"),
1308    ("⫉", "⫊"),
1309    ("⫋", "⫌"),
1310    ("⫍", "⫎"),
1311    ("⫏", "⫐"),
1312    ("⫑", "⫒"),
1313    ("⫓", "⫔"),
1314    ("⫕", "⫖"),
1315    ("⫬", "⫭"),
1316    ("⫷", "⫸"),
1317    ("⫹", "⫺"),
1318    ("⸂", "⸃"),
1319    ("⸄", "⸅"),
1320    ("⸉", "⸊"),
1321    ("⸌", "⸍"),
1322    ("⸜", "⸝"),
1323    ("⸠", "⸡"),
1324    ("⸢", "⸣"),
1325    ("⸤", "⸥"),
1326    ("⸦", "⸧"),
1327    ("⸨", "⸩"),
1328    ("⹕", "⹖"),
1329    ("⹗", "⹘"),
1330    ("⹙", "⹚"),
1331    ("⹛", "⹜"),
1332    ("〈", "〉"),
1333    ("《", "》"),
1334    ("「", "」"),
1335    ("『", "』"),
1336    ("【", "】"),
1337    ("〔", "〕"),
1338    ("〖", "〗"),
1339    ("〘", "〙"),
1340    ("〚", "〛"),
1341    ("﴾", "﴿"),
1342    ("︗", "︘"),
1343    ("︵", "︶"),
1344    ("︷", "︸"),
1345    ("︹", "︺"),
1346    ("︻", "︼"),
1347    ("︽", "︾"),
1348    ("︿", "﹀"),
1349    ("﹁", "﹂"),
1350    ("﹃", "﹄"),
1351    ("﹇", "﹈"),
1352    ("﹙", "﹚"),
1353    ("﹛", "﹜"),
1354    ("﹝", "﹞"),
1355    ("﹤", "﹥"),
1356    ("(", ")"),
1357    ("<", ">"),
1358    ("[", "]"),
1359    ("{", "}"),
1360    ("⦅", "⦆"),
1361    ("「", "」"),
1362];
1363
1364/**
1365Generate a [`BTreeMap`] with the matching close bracket for each open bracket in `UnicodeData.txt`,
1366`BidiBrackets.txt`, and `BidiMirroring.txt`
1367*/
1368#[must_use]
1369pub fn close_all() -> BTreeMap<&'static str, &'static str> {
1370    ALL.iter().copied().collect()
1371}
1372
1373/**
1374Generate a [`BTreeMap`] with the matching open bracket for each close bracket in `UnicodeData.txt`,
1375`BidiBrackets.txt`, and `BidiMirroring.txt`
1376*/
1377#[must_use]
1378pub fn open_all() -> BTreeMap<&'static str, &'static str> {
1379    ALL.iter()
1380        .copied()
1381        .map(|(open, close)| (close, open))
1382        .collect()
1383}
1384
1385/**
1386Generate a [`BTreeMap`] with an entry for each pair of opening and closing brackets in
1387`UnicodeData.txt`, `BidiBrackets.txt`, and `BidiMirroring.txt`
1388*/
1389#[must_use]
1390pub fn matching_all() -> BTreeMap<&'static str, &'static str> {
1391    ALL.iter()
1392        .copied()
1393        .flat_map(|(open, close)| [(open, close), (close, open)])
1394        .collect()
1395}
1396
1397/// Trait to provide the [`FindMatching::find_matching`] method
1398pub trait FindMatching {
1399    /**
1400    Find the index of the matching open or close grapheme for the grapheme at `position`, given the
1401    matching `closing` and `opening` brackets
1402
1403    If the grapheme at `position` is not an opening or closing grapheme, `position` is greater or
1404    equal to the length of `self`, or the algorithm fails to find the matching grapheme (e.g.
1405    matching graphemes are unbalanced), the given `position` is returned.
1406    */
1407    fn find_matching(
1408        &self,
1409        position: usize,
1410        closing: &BTreeMap<&str, &str>,
1411        opening: &BTreeMap<&str, &str>,
1412    ) -> usize;
1413}
1414
1415impl FindMatching for str {
1416    /**
1417    Find the index of the matching open or close grapheme for the grapheme at `position`, given the
1418    matching `closing` and `opening` brackets
1419
1420    If the grapheme at `position` is not an opening or closing grapheme, `position` is greater or
1421    equal to the length of `self`, or the algorithm fails to find the matching grapheme (e.g.
1422    matching graphemes are unbalanced), the given `position` is returned.
1423    */
1424    fn find_matching(
1425        &self,
1426        position: usize,
1427        closing: &BTreeMap<&str, &str>,
1428        opening: &BTreeMap<&str, &str>,
1429    ) -> usize {
1430        self.gstring().find_matching(position, closing, opening)
1431    }
1432}
1433
1434impl FindMatching for GString {
1435    /**
1436    Find the index of the matching open or close grapheme for the grapheme at `position`, given the
1437    matching `closing` and `opening` brackets
1438
1439    If the grapheme at `position` is not an opening or closing grapheme, `position` is greater or
1440    equal to the length of `self`, or the algorithm fails to find the matching grapheme (e.g.
1441    matching graphemes are unbalanced), the given `position` is returned.
1442    */
1443    fn find_matching(
1444        &self,
1445        position: usize,
1446        closing: &BTreeMap<&str, &str>,
1447        opening: &BTreeMap<&str, &str>,
1448    ) -> usize {
1449        let v = self.graphemes();
1450
1451        if position >= v.len() {
1452            return position;
1453        }
1454
1455        let close = closing.get(&v[position].as_str());
1456        let open = opening.get(&v[position].as_str());
1457
1458        if close.is_none() && open.is_none() {
1459            return position;
1460        }
1461
1462        let mut stack: Vec<(usize, &Grapheme)> = vec![];
1463        for (i, g) in v.iter().enumerate() {
1464            if let Some(open) = opening.get(&g.as_str()) {
1465                // g is a close
1466                if let Some(prev) = stack.pop() {
1467                    // There is a previous open
1468                    if prev.1 == open {
1469                        // This close matches the previous open
1470
1471                        if prev.0 == position {
1472                            // Return this close's position if the open is at the position
1473                            return i;
1474                        } else if i == position {
1475                            // Return the previous open's position if this close is at the position
1476                            return prev.0;
1477                        }
1478                    } else if closing.contains_key(&g.as_str()) {
1479                        // This close doesn't match the previous open but is also an open
1480                        stack.push(prev);
1481                        stack.push((i, g));
1482                    } else {
1483                        // This close doesn't match the previous open and is not an open
1484                        // So it's a mismatched close and should just return the position
1485                        return position;
1486                    }
1487                } else if closing.contains_key(&g.as_str()) {
1488                    // There is no previous open and is an open
1489                    stack.push((i, g));
1490                }
1491            } else if closing.contains_key(&g.as_str()) {
1492                // g is an open
1493                stack.push((i, g));
1494            }
1495        }
1496
1497        position
1498    }
1499}