11//! # Mapping charsets to unicode
2- use std:: char:: REPLACEMENT_CHARACTER ;
2+ use std:: { char:: REPLACEMENT_CHARACTER , fmt } ;
33
44use displaydoc:: Display ;
55use nom:: {
@@ -58,29 +58,29 @@ impl ToUnicode for [[char; 2]; 128] {
5858 }
5959}
6060
61+ #[ derive( Clone , PartialEq ) ]
62+ pub ( super ) enum MappingImpl {
63+ Single ( Box < [ char ; 128 ] > ) ,
64+ Static ( & ' static [ char ; 128 ] ) ,
65+ Dynamic ( Box < [ SmallVec < [ char ; 2 ] > ; 128 ] > ) ,
66+ BiLevel ( & ' static [ & ' static [ char ] ; 128 ] ) ,
67+ }
68+
6169/// A mapping table for a charset
62- #[ derive( Debug , Clone , PartialEq ) ]
63- pub enum Mapping {
64- /// The corresponding unicode characters
65- Single {
66- /// characters in this variant
67- chars : Box < [ char ; 128 ] > ,
68- } ,
69- /// The corresponding unicode characters
70- Static {
71- /// characters in this variant
72- chars : & ' static [ char ; 128 ] ,
73- } ,
74- /// The corresponding unicode characters
75- Dynamic {
76- /// characters in this variant
77- chars : Box < [ SmallVec < [ char ; 2 ] > ; 128 ] > ,
78- } ,
79- /// The corresponding unicode characters
80- BiLevel {
81- /// characters in this variant
82- chars : & ' static [ & ' static [ char ] ; 128 ] ,
83- } ,
70+ #[ derive( Clone , PartialEq ) ]
71+ pub struct Mapping ( pub ( super ) MappingImpl ) ;
72+
73+ impl fmt:: Debug for Mapping {
74+ fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
75+ let mut s = f. debug_struct ( "Mapping" ) ;
76+ match & self . 0 {
77+ MappingImpl :: Single ( chars) => s. field ( "chars" , chars) ,
78+ MappingImpl :: Static ( chars) => s. field ( "chars" , chars) ,
79+ MappingImpl :: Dynamic ( chars) => s. field ( "chars" , chars) ,
80+ MappingImpl :: BiLevel ( chars) => s. field ( "chars" , chars) ,
81+ } ;
82+ s. finish ( )
83+ }
8484}
8585
8686impl Mapping {
@@ -96,52 +96,49 @@ impl Mapping {
9696
9797 /// If the mapping can be encoded as a char array, return it
9898 pub fn as_char_array ( & self ) -> Option < & [ char ; 128 ] > {
99- match self {
100- Mapping :: Single { chars } => Some ( chars) ,
101- Mapping :: Static { chars } => Some ( chars) ,
102- Mapping :: Dynamic { chars : _ } => None ,
103- Mapping :: BiLevel { chars : _ } => None ,
99+ match & self . 0 {
100+ MappingImpl :: Single ( chars) => Some ( chars) ,
101+ MappingImpl :: Static ( chars) => Some ( chars) ,
102+ MappingImpl :: Dynamic ( _ ) => None ,
103+ MappingImpl :: BiLevel ( _ ) => None ,
104104 }
105105 }
106- }
107106
108- impl ToUnicode for Mapping {
109- fn decode ( & self , cval : u8 ) -> & [ char ] {
110- match self {
111- Mapping :: Single { chars } => chars. decode ( cval) ,
112- Mapping :: Static { chars } => chars. decode ( cval) ,
113- Mapping :: Dynamic { chars } => chars. decode ( cval) ,
114- Mapping :: BiLevel { chars } => chars. decode ( cval) ,
115- }
107+ /// Create a new static instance
108+ pub const fn new_static ( map : & ' static [ char ; 128 ] ) -> Self {
109+ Self ( MappingImpl :: Static ( map) )
116110 }
117- }
118111
119- impl Mapping {
120- fn new ( chars : [ SmallVec < [ char ; 2 ] > ; 128 ] ) -> Self {
112+ /// Create a new static instance
113+ pub const fn new_static_slices ( map : & ' static [ & ' static [ char ] ; 128 ] ) -> Self {
114+ Self ( MappingImpl :: BiLevel ( map) )
115+ }
116+
117+ /// Create a new instance from an array of vectors
118+ pub fn new ( chars : [ SmallVec < [ char ; 2 ] > ; 128 ] ) -> Self {
121119 if chars. iter ( ) . all ( |c| c. len ( ) <= 1 ) {
122120 let chars = chars. map ( |v| v. first ( ) . copied ( ) . unwrap_or ( REPLACEMENT_CHARACTER ) ) ;
123- Self :: Single {
124- chars : Box :: new ( chars) ,
125- }
121+ Self ( MappingImpl :: Single ( Box :: new ( chars) ) )
126122 } else {
127- Self :: Dynamic {
128- chars : Box :: new ( chars) ,
129- }
123+ Self ( MappingImpl :: Dynamic ( Box :: new ( chars) ) )
130124 }
131125 }
132126}
133127
134- /// The mapping for ANTIKRO
135- pub const ANTIKRO_MAP : Mapping = Mapping :: Static {
136- chars : & antikro :: MAP ,
137- } ;
138-
139- impl Default for & ' _ Mapping {
140- fn default ( ) -> Self {
141- & ANTIKRO_MAP
128+ impl ToUnicode for Mapping {
129+ fn decode ( & self , cval : u8 ) -> & [ char ] {
130+ match & self . 0 {
131+ MappingImpl :: Single ( chars ) => chars . decode ( cval ) ,
132+ MappingImpl :: Static ( chars ) => chars . decode ( cval ) ,
133+ MappingImpl :: Dynamic ( chars ) => chars . decode ( cval ) ,
134+ MappingImpl :: BiLevel ( chars ) => chars . decode ( cval ) ,
135+ }
142136 }
143137}
144138
139+ /// The mapping for ANTIKRO
140+ pub static ANTIKRO_MAP : Mapping = Mapping :: new_static ( & antikro:: MAP ) ;
141+
145142/// Error when parsing a mapping
146143#[ derive( Debug , Display , Error ) ]
147144pub enum MappingError {
0 commit comments