Implement a FromValue trait for SrcVar and Variable. (#227) r=nalexander

This commit is contained in:
Richard Newman 2017-02-01 14:51:02 -08:00
parent 0b3387f8b9
commit 592dec7241
3 changed files with 51 additions and 17 deletions

View file

@ -15,7 +15,7 @@ extern crate mentat_query;
use self::combine::{eof, many1, parser, satisfy_map, Parser, ParseResult, Stream};
use self::combine::combinator::{Expected, FnParser, choice, try};
use self::edn::Value::PlainSymbol;
use self::mentat_query::{Element, FindSpec, Variable};
use self::mentat_query::{Element, FromValue, FindSpec, Variable};
use super::error::{FindParseError, FindParseResult};
@ -45,7 +45,7 @@ impl<I> FindSp<I>
}
fn variable_(input: I) -> ParseResult<Variable, I> {
satisfy_map(|x: edn::Value| super::util::value_to_variable(&x)).parse_stream(input)
satisfy_map(|x: edn::Value| Variable::from_value(&x)).parse_stream(input)
}
fn period() -> FindSpParser<(), I> {

View file

@ -13,28 +13,16 @@ extern crate mentat_query;
use std::collections::BTreeMap;
use self::edn::Value::PlainSymbol;
use self::mentat_query::Variable;
use self::mentat_query::{FromValue, Variable};
use super::error::NotAVariableError;
/// If the provided EDN value is a PlainSymbol beginning with '?', return
/// it wrapped in a Variable. If not, return None.
pub fn value_to_variable(v: &edn::Value) -> Option<Variable> {
if let PlainSymbol(ref sym) = *v {
if sym.0.starts_with('?') {
return Some(Variable(sym.clone()));
}
}
return None;
}
/// If the provided slice of EDN values are all variables as
/// defined by `value_to_variable`, return a Vec of Variables.
/// Otherwise, return the unrecognized Value.
pub fn values_to_variables(vals: &[edn::Value]) -> Result<Vec<Variable>, NotAVariableError> {
let mut out: Vec<Variable> = Vec::with_capacity(vals.len());
for v in vals {
if let Some(var) = value_to_variable(v) {
if let Some(var) = Variable::from_value(v) {
out.push(var);
continue;
}

View file

@ -43,12 +43,58 @@ pub type SrcVarName = String; // Do not include the required syntactic
#[derive(Clone, Debug, PartialEq, Eq)]
pub struct Variable(pub PlainSymbol);
#[derive(Clone,Debug,Eq,PartialEq)]
pub trait FromValue<T> {
fn from_value(v: &edn::Value) -> Option<T>;
}
/// If the provided EDN value is a PlainSymbol beginning with '?', return
/// it wrapped in a Variable. If not, return None.
impl FromValue<Variable> for Variable {
fn from_value(v: &edn::Value) -> Option<Variable> {
if let edn::Value::PlainSymbol(ref s) = *v {
Variable::from_symbol(s)
} else {
None
}
}
}
impl Variable {
fn from_symbol(sym: &PlainSymbol) -> Option<Variable> {
if sym.is_var_symbol() {
Some(Variable(sym.clone()))
} else {
None
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub enum SrcVar {
DefaultSrc,
NamedSrc(SrcVarName),
}
impl FromValue<SrcVar> for SrcVar {
fn from_value(v: &edn::Value) -> Option<SrcVar> {
if let edn::Value::PlainSymbol(ref s) = *v {
SrcVar::from_symbol(s)
} else {
None
}
}
}
impl SrcVar {
pub fn from_symbol(sym: &PlainSymbol) -> Option<SrcVar> {
if sym.is_src_symbol() {
Some(SrcVar::NamedSrc(sym.plain_name().to_string()))
} else {
None
}
}
}
/// These are the scalar values representable in EDN.
#[derive(Clone,Debug,Eq,PartialEq)]
pub enum NonIntegerConstant {