Implement a FromValue trait for SrcVar and Variable. (#227) r=nalexander
This commit is contained in:
parent
0b3387f8b9
commit
592dec7241
3 changed files with 51 additions and 17 deletions
|
@ -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> {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -43,12 +43,58 @@ pub type SrcVarName = String; // Do not include the required syntactic
|
|||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
pub struct Variable(pub PlainSymbol);
|
||||
|
||||
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 {
|
||||
|
|
Loading…
Reference in a new issue