Skip to content

Commit

Permalink
variable: Add default behavior to VarIdx for str parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
Kerollmops committed Jan 7, 2017
1 parent 1c02996 commit 1c82d9f
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 36 deletions.
61 changes: 27 additions & 34 deletions src/evaluate/float.rs
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@ impl<T: Float> fmt::Display for FloatEvaluator<T> {
mod tests {
use expression::{ExprResult, OperandErr};
use evaluate::{FloatErr, FloatExpr, VariableFloatExpr};
use variable::VarIdx;

#[test]
fn bad_operator() {
Expand Down Expand Up @@ -361,47 +362,39 @@ mod tests {
assert_eq!(&expr.to_string(), expr_str);
}

use std::convert::From;
use std::str::FromStr;
use convert_ref::TryFromRef;

#[derive(Copy, Clone)]
struct VarIdx(usize);

#[derive(Debug)]
enum VarIdxErr<'a, E> {
InvalidVariableName(&'a str),
ConvertErr(E),
}

impl<'a> TryFromRef<&'a str> for VarIdx {
type Err = VarIdxErr<'a, <usize as FromStr>::Err>;

fn try_from_ref(s: &&'a str) -> Result<Self, Self::Err> {
match s.chars().next() {
Some('$') => {
match FromStr::from_str(&s[1..]) {
Ok(n) => Ok(VarIdx(n)),
Err(err) => Err(VarIdxErr::ConvertErr(err)),
}
},
_ => Err(VarIdxErr::InvalidVariableName(s)),
}
}
}
#[test]
fn simple_vec_variable_expression() {
let variables = vec![3.0, 500.0];

impl From<VarIdx> for usize {
fn from(var_idx: VarIdx) -> Self {
var_idx.0
}
let expr_str = "3 4 + $0 -";
let tokens = expr_str.split_whitespace();
let expr = VariableFloatExpr::<f32, VarIdx>::from_iter(tokens).unwrap();
assert_eq!(expr.evaluate_with_variables::<usize, _>(variables), Ok(4.0));
}

#[test]
fn simple_variable_expression() {
let expr_str = "3 4 + $0 -";
#[should_panic]
fn invalid_vec_variable_expression() {
let variables = vec![3.0, 500.0];

let expr_str = "3 4 + $2 -";
let tokens = expr_str.split_whitespace();
let expr = VariableFloatExpr::<f32, VarIdx>::from_iter(tokens).unwrap();
assert_eq!(expr.evaluate_with_variables::<usize, _>(variables), Ok(4.0));
}

// #[test]
// fn simple_hashmap_variable_expression() {
// use std::collections::HashMap;
// use std::iter::FromIterator;

// let mut variables = HashMap::new();
// variables.insert(0usize, 3.0);
// variables.insert(42, 500.0);

// let expr_str = "3 4 + $0 -";
// let tokens = expr_str.split_whitespace();
// let expr = VariableFloatExpr::<f32, VarIdx>::from_iter(tokens).unwrap();
// assert_eq!(expr.evaluate_with_variables::<&usize, _>(variables), Ok(4.0));
// }
}
4 changes: 2 additions & 2 deletions src/expression.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ pub enum Arithm<T, V, E: Evaluate<T>> {
/// [`try_into_ref()`]: ../convert_ref/trait.TryIntoRef.html
#[derive(Debug)]
pub struct Expression<T, V, E: Evaluate<T>> {
stack_max: usize,
stack_max: usize, // TODO rename max_stack
expr: Vec<Arithm<T, V, E>>,
}

Expand All @@ -47,7 +47,7 @@ impl<T: Copy, V: Copy, E: Evaluate<T> + Copy> Expression<T, V, E> {
for arithm in &self.expr {
match *arithm {
Arithm::Operand(operand) => stack.push(operand),
Arithm::Variable(var) => stack.push(variables[var.into()]),
Arithm::Variable(var) => stack.push(*variables.index(var.into())),
Arithm::Evaluator(evaluator) => evaluator.evaluate(&mut stack)?,
}
}
Expand Down
2 changes: 2 additions & 0 deletions src/variable/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
mod dummy_variables;
mod dummy_variable;
mod var_idx;

pub use self::dummy_variables::DummyVariables;
pub use self::dummy_variable::DummyVariable;
pub use self::var_idx::VarIdx;
34 changes: 34 additions & 0 deletions src/variable/var_idx.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
use std::convert::From;
use std::str::FromStr;
use convert_ref::TryFromRef;

#[derive(Copy, Clone)]
pub struct VarIdx(usize);

#[derive(Debug)]
pub enum VarIdxErr<'a, E> {
InvalidVariableName(&'a str),
ConvertErr(E),
}

impl<'a> TryFromRef<&'a str> for VarIdx {
type Err = VarIdxErr<'a, <usize as FromStr>::Err>;

fn try_from_ref(s: &&'a str) -> Result<Self, Self::Err> {
match s.chars().next() {
Some('$') => {
match FromStr::from_str(&s[1..]) {
Ok(n) => Ok(VarIdx(n)),
Err(err) => Err(VarIdxErr::ConvertErr(err)),
}
},
_ => Err(VarIdxErr::InvalidVariableName(s)),
}
}
}

impl From<VarIdx> for usize {
fn from(var_idx: VarIdx) -> Self {
var_idx.0
}
}

0 comments on commit 1c82d9f

Please sign in to comment.