Compare commits
No commits in common. "5d8462c6e4465b0beadce99aeff07f3ef5db536d" and "1842d480e188e2b981cc34153a4e09d724dfb84e" have entirely different histories.
5d8462c6e4
...
1842d480e1
1 changed files with 18 additions and 132 deletions
150
src/parse.rs
150
src/parse.rs
|
@ -98,65 +98,25 @@ fn parse_unit(input: String) -> Result<NonMetric, ParseError> {
|
||||||
"st" => Ok(NonMetric::Stone),
|
"st" => Ok(NonMetric::Stone),
|
||||||
|
|
||||||
// Temperature
|
// Temperature
|
||||||
"degree Fahrenheit" => Ok(NonMetric::Fahrenheit),
|
|
||||||
"degrees Fahrenheit" => Ok(NonMetric::Fahrenheit),
|
|
||||||
"degree fahrenheit" => Ok(NonMetric::Fahrenheit),
|
|
||||||
"degrees fahrenheit" => Ok(NonMetric::Fahrenheit),
|
|
||||||
"Fahrenheit" => Ok(NonMetric::Fahrenheit),
|
|
||||||
"fahrenheit" => Ok(NonMetric::Fahrenheit),
|
|
||||||
"°F" => Ok(NonMetric::Fahrenheit),
|
"°F" => Ok(NonMetric::Fahrenheit),
|
||||||
"F" => Ok(NonMetric::Fahrenheit),
|
"F" => Ok(NonMetric::Fahrenheit),
|
||||||
|
|
||||||
// Area
|
// Area
|
||||||
"square inch" => Ok(NonMetric::SquareInch),
|
|
||||||
"square inches" => Ok(NonMetric::SquareInch),
|
|
||||||
"square in" => Ok(NonMetric::SquareInch),
|
|
||||||
"sq inch" => Ok(NonMetric::SquareInch),
|
|
||||||
"sq inches" => Ok(NonMetric::SquareInch),
|
|
||||||
"sq in" => Ok(NonMetric::SquareInch),
|
|
||||||
"inch²" => Ok(NonMetric::SquareInch),
|
"inch²" => Ok(NonMetric::SquareInch),
|
||||||
"inches²" => Ok(NonMetric::SquareInch),
|
"inches²" => Ok(NonMetric::SquareInch),
|
||||||
"in²" => Ok(NonMetric::SquareInch),
|
"in²" => Ok(NonMetric::SquareInch),
|
||||||
"\"²" => Ok(NonMetric::SquareInch),
|
|
||||||
"″²" => Ok(NonMetric::SquareInch),
|
|
||||||
"inch^2" => Ok(NonMetric::SquareInch),
|
|
||||||
"inches^2" => Ok(NonMetric::SquareInch),
|
|
||||||
"in^2" => Ok(NonMetric::SquareInch),
|
|
||||||
"\"^2" => Ok(NonMetric::SquareInch),
|
|
||||||
|
|
||||||
"square foot" => Ok(NonMetric::SquareFoot),
|
|
||||||
"square feet" => Ok(NonMetric::SquareFoot),
|
|
||||||
"square ft" => Ok(NonMetric::SquareFoot),
|
|
||||||
"sq foot" => Ok(NonMetric::SquareFoot),
|
|
||||||
"sq feet" => Ok(NonMetric::SquareFoot),
|
|
||||||
"sq ft" => Ok(NonMetric::SquareFoot),
|
|
||||||
"foot²" => Ok(NonMetric::SquareFoot),
|
"foot²" => Ok(NonMetric::SquareFoot),
|
||||||
"feet²" => Ok(NonMetric::SquareFoot),
|
"feet²" => Ok(NonMetric::SquareFoot),
|
||||||
"ft²" => Ok(NonMetric::SquareFoot),
|
"ft²" => Ok(NonMetric::SquareFoot),
|
||||||
"'²" => Ok(NonMetric::SquareFoot),
|
|
||||||
"′²" => Ok(NonMetric::SquareFoot),
|
|
||||||
"foot^2" => Ok(NonMetric::SquareFoot),
|
|
||||||
"feet^2" => Ok(NonMetric::SquareFoot),
|
|
||||||
"ft^2" => Ok(NonMetric::SquareFoot),
|
|
||||||
"'^2" => Ok(NonMetric::SquareFoot),
|
|
||||||
"sf" => Ok(NonMetric::SquareFoot),
|
|
||||||
|
|
||||||
"acre" => Ok(NonMetric::Acre),
|
"acre" => Ok(NonMetric::Acre),
|
||||||
"acres" => Ok(NonMetric::Acre),
|
"acres" => Ok(NonMetric::Acre),
|
||||||
"ac" => Ok(NonMetric::Acre),
|
"ac" => Ok(NonMetric::Acre),
|
||||||
|
|
||||||
"square mile" => Ok(NonMetric::SquareMile),
|
|
||||||
"square miles" => Ok(NonMetric::SquareMile),
|
|
||||||
"square mi" => Ok(NonMetric::SquareMile),
|
|
||||||
"sq mile" => Ok(NonMetric::SquareMile),
|
|
||||||
"sq miles" => Ok(NonMetric::SquareMile),
|
|
||||||
"sq mi" => Ok(NonMetric::SquareMile),
|
|
||||||
"mile²" => Ok(NonMetric::SquareMile),
|
"mile²" => Ok(NonMetric::SquareMile),
|
||||||
"miles²" => Ok(NonMetric::SquareMile),
|
"miles²" => Ok(NonMetric::SquareMile),
|
||||||
"mi²" => Ok(NonMetric::SquareMile),
|
"mi²" => Ok(NonMetric::SquareMile),
|
||||||
"mile^2" => Ok(NonMetric::SquareMile),
|
|
||||||
"miles^2" => Ok(NonMetric::SquareMile),
|
|
||||||
"mi^2" => Ok(NonMetric::SquareMile),
|
|
||||||
|
|
||||||
_ => Err(ParseError::UnknownUnit(input)),
|
_ => Err(ParseError::UnknownUnit(input)),
|
||||||
}
|
}
|
||||||
|
@ -171,7 +131,7 @@ enum Token {
|
||||||
enum TokState {
|
enum TokState {
|
||||||
Neutral,
|
Neutral,
|
||||||
Number,
|
Number,
|
||||||
Unit(bool),
|
Unit,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn tokenize(input: &str) -> Vec<Token> {
|
fn tokenize(input: &str) -> Vec<Token> {
|
||||||
|
@ -187,7 +147,7 @@ fn tokenize(input: &str) -> Vec<Token> {
|
||||||
state = TokState::Number;
|
state = TokState::Number;
|
||||||
} else if !c.is_whitespace() {
|
} else if !c.is_whitespace() {
|
||||||
token.push(c);
|
token.push(c);
|
||||||
state = TokState::Unit(false);
|
state = TokState::Unit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TokState::Number => {
|
TokState::Number => {
|
||||||
|
@ -197,25 +157,23 @@ fn tokenize(input: &str) -> Vec<Token> {
|
||||||
token.push(c);
|
token.push(c);
|
||||||
} else {
|
} else {
|
||||||
tokens.push(Token::Number(token.trim().to_string()));
|
tokens.push(Token::Number(token.trim().to_string()));
|
||||||
state = TokState::Unit(false);
|
state = TokState::Unit;
|
||||||
token = String::new();
|
token = String::new();
|
||||||
token.push(c);
|
token.push(c);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TokState::Unit(after_caret) => {
|
TokState::Unit => {
|
||||||
if !after_caret && (c.is_ascii_digit() || c == '-') {
|
if c.is_ascii_digit() || c == '-' {
|
||||||
tokens.push(Token::Unit(token.trim().to_string()));
|
tokens.push(Token::Unit(token));
|
||||||
state = TokState::Number;
|
state = TokState::Number;
|
||||||
token = String::new();
|
token = String::new();
|
||||||
token.push(c);
|
token.push(c);
|
||||||
} else if c == '^' {
|
} else if !c.is_whitespace() {
|
||||||
token.push(c);
|
token.push(c);
|
||||||
state = TokState::Unit(true);
|
|
||||||
} else if c.is_whitespace() {
|
|
||||||
token.push(c);
|
|
||||||
state = TokState::Unit(false);
|
|
||||||
} else {
|
} else {
|
||||||
token.push(c);
|
tokens.push(Token::Unit(token));
|
||||||
|
state = TokState::Neutral;
|
||||||
|
token = String::new();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -224,7 +182,7 @@ fn tokenize(input: &str) -> Vec<Token> {
|
||||||
match state {
|
match state {
|
||||||
TokState::Neutral => { assert!(token.len() == 0); }
|
TokState::Neutral => { assert!(token.len() == 0); }
|
||||||
TokState::Number => { tokens.push(Token::Number(token.trim().to_string())); }
|
TokState::Number => { tokens.push(Token::Number(token.trim().to_string())); }
|
||||||
TokState::Unit(_) => { tokens.push(Token::Unit(token.trim().to_string())); }
|
TokState::Unit => { tokens.push(Token::Unit(token)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
tokens
|
tokens
|
||||||
|
@ -305,65 +263,25 @@ mod test {
|
||||||
assert_eq!(parse_unit("st".to_string()), Ok(NonMetric::Stone));
|
assert_eq!(parse_unit("st".to_string()), Ok(NonMetric::Stone));
|
||||||
|
|
||||||
// Temperature
|
// Temperature
|
||||||
assert_eq!(parse_unit("degree Fahrenheit".to_string()), Ok(NonMetric::Fahrenheit));
|
|
||||||
assert_eq!(parse_unit("degrees Fahrenheit".to_string()), Ok(NonMetric::Fahrenheit));
|
|
||||||
assert_eq!(parse_unit("degree fahrenheit".to_string()), Ok(NonMetric::Fahrenheit));
|
|
||||||
assert_eq!(parse_unit("degrees fahrenheit".to_string()), Ok(NonMetric::Fahrenheit));
|
|
||||||
assert_eq!(parse_unit("Fahrenheit".to_string()), Ok(NonMetric::Fahrenheit));
|
|
||||||
assert_eq!(parse_unit("fahrenheit".to_string()), Ok(NonMetric::Fahrenheit));
|
|
||||||
assert_eq!(parse_unit("°F".to_string()), Ok(NonMetric::Fahrenheit));
|
assert_eq!(parse_unit("°F".to_string()), Ok(NonMetric::Fahrenheit));
|
||||||
assert_eq!(parse_unit("F".to_string()), Ok(NonMetric::Fahrenheit));
|
assert_eq!(parse_unit("F".to_string()), Ok(NonMetric::Fahrenheit));
|
||||||
|
|
||||||
// Area
|
// Area
|
||||||
assert_eq!(parse_unit("square inch".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("square inches".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("square in".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("sq inch".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("sq inches".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("sq in".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("inch²".to_string()), Ok(NonMetric::SquareInch));
|
assert_eq!(parse_unit("inch²".to_string()), Ok(NonMetric::SquareInch));
|
||||||
assert_eq!(parse_unit("inches²".to_string()), Ok(NonMetric::SquareInch));
|
assert_eq!(parse_unit("inches²".to_string()), Ok(NonMetric::SquareInch));
|
||||||
assert_eq!(parse_unit("in²".to_string()), Ok(NonMetric::SquareInch));
|
assert_eq!(parse_unit("in²".to_string()), Ok(NonMetric::SquareInch));
|
||||||
assert_eq!(parse_unit("\"²".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("″²".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("inch^2".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("inches^2".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("in^2".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
assert_eq!(parse_unit("\"^2".to_string()), Ok(NonMetric::SquareInch));
|
|
||||||
|
|
||||||
assert_eq!(parse_unit("square foot".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("square feet".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("square ft".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("sq foot".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("sq feet".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("sq ft".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("foot²".to_string()), Ok(NonMetric::SquareFoot));
|
assert_eq!(parse_unit("foot²".to_string()), Ok(NonMetric::SquareFoot));
|
||||||
assert_eq!(parse_unit("feet²".to_string()), Ok(NonMetric::SquareFoot));
|
assert_eq!(parse_unit("feet²".to_string()), Ok(NonMetric::SquareFoot));
|
||||||
assert_eq!(parse_unit("ft²".to_string()), Ok(NonMetric::SquareFoot));
|
assert_eq!(parse_unit("ft²".to_string()), Ok(NonMetric::SquareFoot));
|
||||||
assert_eq!(parse_unit("'²".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("′²".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("foot^2".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("feet^2".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("ft^2".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("'^2".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
assert_eq!(parse_unit("sf".to_string()), Ok(NonMetric::SquareFoot));
|
|
||||||
|
|
||||||
assert_eq!(parse_unit("acre".to_string()), Ok(NonMetric::Acre));
|
assert_eq!(parse_unit("acre".to_string()), Ok(NonMetric::Acre));
|
||||||
assert_eq!(parse_unit("acres".to_string()), Ok(NonMetric::Acre));
|
assert_eq!(parse_unit("acres".to_string()), Ok(NonMetric::Acre));
|
||||||
assert_eq!(parse_unit("ac".to_string()), Ok(NonMetric::Acre));
|
assert_eq!(parse_unit("ac".to_string()), Ok(NonMetric::Acre));
|
||||||
|
|
||||||
assert_eq!(parse_unit("square mile".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("square miles".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("square mi".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("sq mile".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("sq miles".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("sq mi".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("mile²".to_string()), Ok(NonMetric::SquareMile));
|
assert_eq!(parse_unit("mile²".to_string()), Ok(NonMetric::SquareMile));
|
||||||
assert_eq!(parse_unit("miles²".to_string()), Ok(NonMetric::SquareMile));
|
assert_eq!(parse_unit("miles²".to_string()), Ok(NonMetric::SquareMile));
|
||||||
assert_eq!(parse_unit("mi²".to_string()), Ok(NonMetric::SquareMile));
|
assert_eq!(parse_unit("mi²".to_string()), Ok(NonMetric::SquareMile));
|
||||||
assert_eq!(parse_unit("mile^2".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("miles^2".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
assert_eq!(parse_unit("mi^2".to_string()), Ok(NonMetric::SquareMile));
|
|
||||||
|
|
||||||
// Unknown unit
|
// Unknown unit
|
||||||
assert_eq!(parse_unit("hutenosa".to_string()), Err(ParseError::UnknownUnit("hutenosa".to_string())));
|
assert_eq!(parse_unit("hutenosa".to_string()), Err(ParseError::UnknownUnit("hutenosa".to_string())));
|
||||||
|
@ -386,6 +304,13 @@ mod test {
|
||||||
Token::Unit("ft".to_string()),
|
Token::Unit("ft".to_string()),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
tokenize("ft in"),
|
||||||
|
vec![
|
||||||
|
Token::Unit("ft".to_string()),
|
||||||
|
Token::Unit("in".to_string()),
|
||||||
|
]
|
||||||
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tokenize("5 ft 7 in"),
|
tokenize("5 ft 7 in"),
|
||||||
vec![
|
vec![
|
||||||
|
@ -411,44 +336,5 @@ mod test {
|
||||||
Token::Unit("lbs".to_string()),
|
Token::Unit("lbs".to_string()),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
assert_eq!(
|
|
||||||
tokenize("sq ft"),
|
|
||||||
vec![
|
|
||||||
Token::Unit("sq ft".to_string()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
tokenize("sq ft2"),
|
|
||||||
vec![
|
|
||||||
Token::Unit("sq ft".to_string()),
|
|
||||||
Token::Number("2".to_string()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
tokenize("ft^2"),
|
|
||||||
vec![
|
|
||||||
Token::Unit("ft^2".to_string()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
tokenize("ft^22"),
|
|
||||||
vec![
|
|
||||||
Token::Unit("ft^22".to_string()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
tokenize("ft^2 2"),
|
|
||||||
vec![
|
|
||||||
Token::Unit("ft^2".to_string()),
|
|
||||||
Token::Number("2".to_string()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
assert_eq!(
|
|
||||||
tokenize("ft^2 s^-1 lb 2"),
|
|
||||||
vec![
|
|
||||||
Token::Unit("ft^2 s^-1 lb".to_string()),
|
|
||||||
Token::Number("2".to_string()),
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue