mirror of
https://github.com/tiffany352/rink-rs
synced 2024-11-10 13:44:15 +00:00
Canonicalize user input units
This commit is contained in:
parent
262ee80a7c
commit
6180935d63
1 changed files with 36 additions and 2 deletions
38
src/eval.rs
38
src/eval.rs
|
@ -189,6 +189,39 @@ impl Context {
|
|||
None
|
||||
}
|
||||
|
||||
/// Given a unit name, try to return a canonical name (expanding aliases and such)
|
||||
pub fn canonicalize(&self, name: &str) -> Option<String> {
|
||||
for k in &self.dimensions {
|
||||
if name == &***k {
|
||||
return Some((**k).clone())
|
||||
}
|
||||
}
|
||||
if let Some(v) = self.definitions.get(name) {
|
||||
if let Expr::Unit(ref name) = *v {
|
||||
if let Some(r) = self.canonicalize(&*name) {
|
||||
return Some(r)
|
||||
} else {
|
||||
return Some(name.clone())
|
||||
}
|
||||
}
|
||||
// we cannot canonicalize it further
|
||||
return None
|
||||
}
|
||||
if name.ends_with("s") {
|
||||
if let Some(v) = self.canonicalize(&name[0..name.len()-1]) {
|
||||
return Some(v)
|
||||
}
|
||||
}
|
||||
for &(ref pre, _) in &self.prefixes {
|
||||
if name.starts_with(pre) {
|
||||
if let Some(v) = self.canonicalize(&name[pre.len()..]) {
|
||||
return Some(format!("{}{}", pre, v))
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Describes a value's unit, gives true if the unit is reciprocal
|
||||
/// (e.g. you should prefix "1.0 / " or replace "multiply" with
|
||||
/// "divide" when rendering it).
|
||||
|
@ -369,7 +402,7 @@ impl Context {
|
|||
Expr::Call(_, _) => Err(format!("Calls are not allowed in the right hand side of conversions")),
|
||||
Expr::Unit(ref name) | Expr::Quote(ref name) => {
|
||||
let mut map = BTreeMap::new();
|
||||
map.insert(name.clone(), 1);
|
||||
map.insert(self.canonicalize(&**name).unwrap_or_else(|| name.clone()), 1);
|
||||
Ok(map)
|
||||
},
|
||||
Expr::Const(ref x, None, None) if x == "1" || x == "-1" => Ok(BTreeMap::new()),
|
||||
|
@ -598,7 +631,8 @@ impl Context {
|
|||
use std::io::Write;
|
||||
use number;
|
||||
|
||||
write!(buf, "{} {}, ", number::to_string(&value).1, name).unwrap();
|
||||
write!(buf, "{} {}, ", number::to_string(&value).1,
|
||||
self.canonicalize(name).unwrap_or_else(|| name.clone())).unwrap();
|
||||
}
|
||||
buf.pop(); buf.pop();
|
||||
if let Some(res) = self.aliases.get(&top.1) {
|
||||
|
|
Loading…
Reference in a new issue