Skip to content

Commit

Permalink
A sketch of numeric operations and comparison
Browse files Browse the repository at this point in the history
  • Loading branch information
tailhook committed Aug 15, 2017
1 parent d5893ff commit c3a07e0
Show file tree
Hide file tree
Showing 5 changed files with 106 additions and 2 deletions.
44 changes: 44 additions & 0 deletions src/compare.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/// An internal representation of something that can be compared
///
/// Only numbers and strings can be compared for now.
///
/// Use `into()` conversion to make the value.
pub struct Comparable<'a>(ComparableInner<'a>);

enum ComparableInner<'a> {
I64(i64),
U64(u64),
F64(f64),
Str(&'a str),
String(String),
}

impl<'a> From<i64> for Comparable<'a> {
fn from(x: i64) -> Comparable<'a> {
Comparable(ComparableInner::I64(x))
}
}

impl<'a> From<u64> for Comparable<'a> {
fn from(x: u64) -> Comparable<'a> {
Comparable(ComparableInner::U64(x))
}
}

impl<'a> From<f64> for Comparable<'a> {
fn from(x: f64) -> Comparable<'a> {
Comparable(ComparableInner::F64(x))
}
}

impl<'a> From<&'a str> for Comparable<'a> {
fn from(x: &'a str) -> Comparable<'a> {
Comparable(ComparableInner::Str(x))
}
}

impl<'a> From<String> for Comparable<'a> {
fn from(x: String) -> Comparable<'a> {
Comparable(ComparableInner::String(x))
}
}
4 changes: 4 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,11 @@ extern crate regex;
#[macro_use] extern crate matches;
#[cfg(feature="json")] extern crate serde_json;

mod compare;
mod grammar;
mod helpers;
mod indent;
mod number;
mod oneline;
mod optimize;
mod options;
Expand All @@ -42,6 +44,8 @@ pub use render_error::{RenderError, DataError};
pub use render::Template;
pub use vars::{Variable};
pub use varmap::Context;
pub use number::Number;
pub use compare::Comparable;
#[cfg(feature="json")] pub use serde::render_json;

use std::collections::HashMap;
Expand Down
28 changes: 28 additions & 0 deletions src/number.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/// An internal representation of a number that may be integer of real
///
/// Use `into()` conversion to make the value.
pub struct Number(NumberInner);

enum NumberInner {
I64(i64),
U64(u64),
F64(f64),
}

impl From<i64> for Number {
fn from(x: i64) -> Number {
Number(NumberInner::I64(x))
}
}

impl From<u64> for Number {
fn from(x: u64) -> Number {
Number(NumberInner::U64(x))
}
}

impl From<f64> for Number {
fn from(x: f64) -> Number {
Number(NumberInner::F64(x))
}
}
10 changes: 10 additions & 0 deletions src/render_error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,16 @@ quick_error! {
description("can't treat object of this type as bool")
display("can't treat object of type {} as bool", typename)
}
/// The object can't be a number
NumberUnsupported(typename: &'static str) {
description("can't treat object of this type as number")
display("can't treat object of type {} as number", typename)
}
/// The object can't be compared to
ComparisonUnsupported(typename: &'static str) {
description("can't compare objects of this type")
display("can't compare objects of type {}", typename)
}
/// The object can't be iterated over
IterationUnsupported(typename: &'static str) {
description("can't iterate over the object")
Expand Down
22 changes: 20 additions & 2 deletions src/vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::iter::empty;

use render_error::DataError;
use owning_ref::{OwningRef, Erased};
use {Var, Output};
use {Var, Output, Number, Comparable};

pub type VarRef<'render> = OwningRef<Rc<Erased+'render>,
Variable<'render>+'render>;
Expand All @@ -14,7 +14,6 @@ pub enum Val<'a, 'render: 'a>{
Rc(VarRef<'render>),
}


#[derive(Debug)]
pub struct Undefined;

Expand Down Expand Up @@ -93,6 +92,25 @@ pub trait Variable<'render>: Debug {
Err(DataError::BoolUnsupported(self.typename()))
}

/// Return value as it could be treated in numeric context
///
/// Numeric context is where `+,-,*,/,%` operators are used. Use standard
/// `into()` conversion to convert built-in value into internal
/// representation.
fn as_number(&self) -> Result<Number, DataError> {
Err(DataError::NumberUnsupported(self.typename()))
}

/// Return value of the object that might be compared to another value
///
/// Note we can only compare numbers with number and strings with
/// strings. All other types of comparisons are unsupported. Use standard
/// `into()` conversion to convert built-in value into internal
/// representation.
fn as_comparable(&self) -> Result<Comparable, DataError> {
Err(DataError::ComparisonUnsupported(self.typename()))
}

/// Return iterator over the value if appropriate
fn iterate<'x>(&'x self)
-> Result<Box<Iterator<Item=Var<'x, 'render>>+'x>, DataError>
Expand Down

0 comments on commit c3a07e0

Please sign in to comment.