Skip to content

Commit 1c6bced

Browse files
committed
Extract the functionality to derive an attribute from a string
into a method of AttributeMapping
1 parent 841a217 commit 1c6bced

File tree

2 files changed

+38
-8
lines changed

2 files changed

+38
-8
lines changed

src/parser/match_rule.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ pub enum ParseError {
1616
InvalidEscape,
1717
}
1818

19-
#[derive(Debug, PartialEq, Eq, Hash)]
19+
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
2020
pub enum Attribute {
2121
Space,
2222
Digit,

src/translator.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -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)]
159189
pub 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

Comments
 (0)