@@ -26,6 +26,8 @@ pub enum TranslationError {
2626 derived : char ,
2727 direction : Direction ,
2828 } ,
29+ #[ error( "Attribute {0:?} has not been defined" ) ]
30+ AttributeNotDefined ( String ) ,
2931}
3032
3133#[ derive( Debug , PartialEq , Clone , Default ) ]
@@ -155,11 +157,40 @@ impl CharacterAttributes {
155157 }
156158}
157159
160+ /// A mapping between a name of an attribute and it's enum
161+ #[ derive( Debug , Default ) ]
162+ struct AttributeMapping ( HashMap < String , Attribute > ) ;
163+
164+ impl AttributeMapping {
165+ fn new ( ) -> Self {
166+ Self ( HashMap :: from ( [
167+ ( "space" . to_string ( ) , Attribute :: Space ) ,
168+ ( "digit" . to_string ( ) , Attribute :: Digit ) ,
169+ ( "letter" . to_string ( ) , Attribute :: Letter ) ,
170+ ( "lowercase" . to_string ( ) , Attribute :: Lowercase ) ,
171+ ( "uppercase" . to_string ( ) , Attribute :: Uppercase ) ,
172+ ( "punctuation" . to_string ( ) , Attribute :: Punctuation ) ,
173+ ( "sign" . to_string ( ) , Attribute :: Sign ) ,
174+ //("math".to_string(), Attribute::Math),
175+ //("litdigit".to_string(), Attribute::LitDigit),
176+ ] ) )
177+ }
178+
179+ fn insert ( & mut self , name : & str , attribute : Attribute ) {
180+ self . 0 . entry ( name. to_string ( ) ) . or_insert ( attribute) ;
181+ }
182+
183+ fn get ( & self , name : & str ) -> Option < Attribute > {
184+ self . 0 . get ( name) . cloned ( )
185+ }
186+ }
187+
158188#[ derive( Debug ) ]
159189pub struct TranslationTable {
160190 undefined : Option < String > ,
161191 character_definitions : CharacterDefinition ,
162192 character_attributes : CharacterAttributes ,
193+ attributes : AttributeMapping ,
163194 translations : Trie ,
164195 match_patterns : MatchPatterns ,
165196 numeric_indicator : numeric:: Indicator ,
@@ -175,6 +206,7 @@ impl TranslationTable {
175206 let mut undefined = None ;
176207 let mut character_definitions = CharacterDefinition :: new ( ) ;
177208 let mut character_attributes = CharacterAttributes :: new ( ) ;
209+ let mut attributes = AttributeMapping :: new ( ) ;
178210 let mut translations = Trie :: new ( ) ;
179211 let mut match_patterns = MatchPatterns :: new ( ) ;
180212 let mut numeric_indicator_builder = numeric:: IndicatorBuilder :: new ( ) ;
@@ -346,13 +378,10 @@ impl TranslationTable {
346378 ..translation. clone ( )
347379 } ,
348380 ) ;
349- // FIXME: The functionality to derive an attribute from a string should be
350- // separated out. Also it should support more than "uppercase" :-)
351- match & name[ ..] {
352- "uppercase" => {
353- character_attributes. insert ( Attribute :: Uppercase , * derived)
354- }
355- _ => ( ) ,
381+ if let Some ( attribute) = attributes. get ( name) {
382+ character_attributes. insert ( attribute, * derived)
383+ } else {
384+ return Err ( TranslationError :: AttributeNotDefined ( name. to_string ( ) ) ) ;
356385 }
357386 } else {
358387 // hm, there is no character definition for the base character.
@@ -469,6 +498,7 @@ impl TranslationTable {
469498 direction,
470499 character_definitions,
471500 character_attributes,
501+ attributes,
472502 translations,
473503 match_patterns,
474504 numeric_indicator : numeric_indicator_builder. build ( ) ,
0 commit comments