Review comment: Make or
be or_exactly
.
I baked the eof checking directly into the parser, rather than using the skip and eof parsers. I also took the time to restore some tests that were mistakenly commented out.
This commit is contained in:
parent
f8e75d817e
commit
0165a842ef
3 changed files with 126 additions and 128 deletions
|
@ -22,7 +22,6 @@ use combine::{
|
||||||
Parser,
|
Parser,
|
||||||
ParseResult,
|
ParseResult,
|
||||||
StreamOnce,
|
StreamOnce,
|
||||||
eof,
|
|
||||||
many,
|
many,
|
||||||
many1,
|
many1,
|
||||||
parser,
|
parser,
|
||||||
|
@ -35,10 +34,8 @@ use combine::primitives::{
|
||||||
FastResult,
|
FastResult,
|
||||||
};
|
};
|
||||||
use combine::combinator::{
|
use combine::combinator::{
|
||||||
Eof,
|
|
||||||
Expected,
|
Expected,
|
||||||
FnParser,
|
FnParser,
|
||||||
Skip,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
use edn;
|
use edn;
|
||||||
|
@ -165,9 +162,9 @@ impl Item for edn::ValueAndSpan {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// `Of` and `of` allow us to express nested parsers naturally.
|
/// `OfExactly` and `of_exactly` allow us to express nested parsers naturally.
|
||||||
///
|
///
|
||||||
/// For example, `vector().of(many(list()))` parses a vector-of-lists, like [(1 2) (:a :b) ("test") ()].
|
/// For example, `vector().of_exactly(many(list()))` parses a vector-of-lists, like [(1 2) (:a :b) ("test") ()].
|
||||||
///
|
///
|
||||||
/// The "outer" parser `P` and the "nested" parser `N` must be compatible: `P` must produce an
|
/// The "outer" parser `P` and the "nested" parser `N` must be compatible: `P` must produce an
|
||||||
/// output `edn::ValueAndSpan` which can itself be turned into a stream of child elements; and `N`
|
/// output `edn::ValueAndSpan` which can itself be turned into a stream of child elements; and `N`
|
||||||
|
@ -175,9 +172,9 @@ impl Item for edn::ValueAndSpan {
|
||||||
/// nested parser to the outer parser, which is part of what has made parsing `&'a [edn::Value]`
|
/// nested parser to the outer parser, which is part of what has made parsing `&'a [edn::Value]`
|
||||||
/// difficult.
|
/// difficult.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Of<P, N>(P, N);
|
pub struct OfExactly<P, N>(P, N);
|
||||||
|
|
||||||
impl<P, N, O> Parser for Of<P, N>
|
impl<P, N, O> Parser for OfExactly<P, N>
|
||||||
where P: Parser<Input=Stream, Output=edn::ValueAndSpan>,
|
where P: Parser<Input=Stream, Output=edn::ValueAndSpan>,
|
||||||
N: Parser<Input=Stream, Output=O>,
|
N: Parser<Input=Stream, Output=O>,
|
||||||
{
|
{
|
||||||
|
@ -190,7 +187,12 @@ impl<P, N, O> Parser for Of<P, N>
|
||||||
match self.0.parse_lazy(input) {
|
match self.0.parse_lazy(input) {
|
||||||
ConsumedOk((outer_value, outer_input)) => {
|
ConsumedOk((outer_value, outer_input)) => {
|
||||||
match self.1.parse_lazy(outer_value.into_child_stream()) {
|
match self.1.parse_lazy(outer_value.into_child_stream()) {
|
||||||
ConsumedOk((inner_value, _)) | EmptyOk((inner_value, _)) => ConsumedOk((inner_value, outer_input)),
|
ConsumedOk((inner_value, mut inner_input)) | EmptyOk((inner_value, mut inner_input)) => {
|
||||||
|
match inner_input.uncons() {
|
||||||
|
Err(ref err) if *err == primitives::Error::end_of_input() => ConsumedOk((inner_value, outer_input)),
|
||||||
|
_ => EmptyErr(ParseError::empty(inner_input.position())),
|
||||||
|
}
|
||||||
|
},
|
||||||
// TODO: Improve the error output to reference the nested value (or span) in
|
// TODO: Improve the error output to reference the nested value (or span) in
|
||||||
// some way. This seems surprisingly difficult to do, so we just surface the
|
// some way. This seems surprisingly difficult to do, so we just surface the
|
||||||
// inner error message right now. See also the comment below.
|
// inner error message right now. See also the comment below.
|
||||||
|
@ -199,7 +201,12 @@ impl<P, N, O> Parser for Of<P, N>
|
||||||
},
|
},
|
||||||
EmptyOk((outer_value, outer_input)) => {
|
EmptyOk((outer_value, outer_input)) => {
|
||||||
match self.1.parse_lazy(outer_value.into_child_stream()) {
|
match self.1.parse_lazy(outer_value.into_child_stream()) {
|
||||||
ConsumedOk((inner_value, _)) | EmptyOk((inner_value, _)) => EmptyOk((inner_value, outer_input)),
|
ConsumedOk((inner_value, mut inner_input)) | EmptyOk((inner_value, mut inner_input)) => {
|
||||||
|
match inner_input.uncons() {
|
||||||
|
Err(ref err) if *err == primitives::Error::end_of_input() => EmptyOk((inner_value, outer_input)),
|
||||||
|
_ => EmptyErr(ParseError::empty(inner_input.position())),
|
||||||
|
}
|
||||||
|
},
|
||||||
// TODO: Improve the error output. See the comment above.
|
// TODO: Improve the error output. See the comment above.
|
||||||
EmptyErr(e) | ConsumedErr(e) => EmptyErr(e),
|
EmptyErr(e) | ConsumedErr(e) => EmptyErr(e),
|
||||||
}
|
}
|
||||||
|
@ -215,27 +222,27 @@ impl<P, N, O> Parser for Of<P, N>
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn of<P, N, O>(p: P, n: N) -> Of<P, Skip<N, Eof<Stream>>>
|
pub fn of_exactly<P, N, O>(p: P, n: N) -> OfExactly<P, N>
|
||||||
where P: Parser<Input=Stream, Output=edn::ValueAndSpan>,
|
where P: Parser<Input=Stream, Output=edn::ValueAndSpan>,
|
||||||
N: Parser<Input=Stream, Output=O>,
|
N: Parser<Input=Stream, Output=O>,
|
||||||
{
|
{
|
||||||
Of(p, n.skip(eof()))
|
OfExactly(p, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// We need a trait to define `Parser.of` and have it live outside of the `combine` crate.
|
/// We need a trait to define `Parser.of` and have it live outside of the `combine` crate.
|
||||||
pub trait OfParsing: Parser + Sized {
|
pub trait OfExactlyParsing: Parser + Sized {
|
||||||
fn of<N, O>(self, n: N) -> Of<Self, Skip<N, Eof<Self::Input>>>
|
fn of_exactly<N, O>(self, n: N) -> OfExactly<Self, N>
|
||||||
where Self: Sized,
|
where Self: Sized,
|
||||||
N: Parser<Input = Self::Input, Output=O>;
|
N: Parser<Input = Self::Input, Output=O>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<P> OfParsing for P
|
impl<P> OfExactlyParsing for P
|
||||||
where P: Parser<Input=Stream, Output=edn::ValueAndSpan>
|
where P: Parser<Input=Stream, Output=edn::ValueAndSpan>
|
||||||
{
|
{
|
||||||
fn of<N, O>(self, n: N) -> Of<P, Skip<N, Eof<Self::Input>>>
|
fn of_exactly<N, O>(self, n: N) -> OfExactly<P, N>
|
||||||
where N: Parser<Input = Self::Input, Output=O>
|
where N: Parser<Input = Self::Input, Output=O>
|
||||||
{
|
{
|
||||||
of(self, n)
|
of_exactly(self, n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -311,7 +318,7 @@ fn keyword_map_(input: Stream) -> ParseResult<edn::ValueAndSpan, Stream>
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
||||||
let mut runs = vector().of(many::<Vec<_>, _>(run));
|
let mut runs = vector().of_exactly(many::<Vec<_>, _>(run));
|
||||||
|
|
||||||
let (data, input) = try!(runs.parse_lazy(input).into());
|
let (data, input) = try!(runs.parse_lazy(input).into());
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ use self::mentat_parser_utils::{
|
||||||
use self::mentat_parser_utils::value_and_span::Stream as ValueStream;
|
use self::mentat_parser_utils::value_and_span::Stream as ValueStream;
|
||||||
use self::mentat_parser_utils::value_and_span::{
|
use self::mentat_parser_utils::value_and_span::{
|
||||||
Item,
|
Item,
|
||||||
OfParsing,
|
OfExactlyParsing,
|
||||||
keyword_map,
|
keyword_map,
|
||||||
list,
|
list,
|
||||||
map,
|
map,
|
||||||
|
@ -162,7 +162,7 @@ def_parser!(Where, or_join, edn::ValueAndSpan, {
|
||||||
|
|
||||||
def_parser!(Where, rule_vars, Vec<Variable>, {
|
def_parser!(Where, rule_vars, Vec<Variable>, {
|
||||||
seq()
|
seq()
|
||||||
.of(many1(Query::variable()))
|
.of_exactly(many1(Query::variable()))
|
||||||
});
|
});
|
||||||
|
|
||||||
def_parser!(Where, or_pattern_clause, OrWhereClause, {
|
def_parser!(Where, or_pattern_clause, OrWhereClause, {
|
||||||
|
@ -171,7 +171,7 @@ def_parser!(Where, or_pattern_clause, OrWhereClause, {
|
||||||
|
|
||||||
def_parser!(Where, or_and_clause, OrWhereClause, {
|
def_parser!(Where, or_and_clause, OrWhereClause, {
|
||||||
seq()
|
seq()
|
||||||
.of(Where::and()
|
.of_exactly(Where::and()
|
||||||
.with(many1(Where::clause()))
|
.with(many1(Where::clause()))
|
||||||
.map(OrWhereClause::And))
|
.map(OrWhereClause::And))
|
||||||
});
|
});
|
||||||
|
@ -182,7 +182,7 @@ def_parser!(Where, or_where_clause, OrWhereClause, {
|
||||||
|
|
||||||
def_parser!(Where, or_clause, WhereClause, {
|
def_parser!(Where, or_clause, WhereClause, {
|
||||||
seq()
|
seq()
|
||||||
.of(Where::or()
|
.of_exactly(Where::or()
|
||||||
.with(many1(Where::or_where_clause()))
|
.with(many1(Where::or_where_clause()))
|
||||||
.map(|clauses| {
|
.map(|clauses| {
|
||||||
WhereClause::OrJoin(
|
WhereClause::OrJoin(
|
||||||
|
@ -195,7 +195,7 @@ def_parser!(Where, or_clause, WhereClause, {
|
||||||
|
|
||||||
def_parser!(Where, or_join_clause, WhereClause, {
|
def_parser!(Where, or_join_clause, WhereClause, {
|
||||||
seq()
|
seq()
|
||||||
.of(Where::or_join()
|
.of_exactly(Where::or_join()
|
||||||
.with(Where::rule_vars())
|
.with(Where::rule_vars())
|
||||||
.and(many1(Where::or_where_clause()))
|
.and(many1(Where::or_where_clause()))
|
||||||
.map(|(vars, clauses)| {
|
.map(|(vars, clauses)| {
|
||||||
|
@ -212,8 +212,8 @@ def_parser!(Where, pred, WhereClause, {
|
||||||
// Accept either a nested list or a nested vector here:
|
// Accept either a nested list or a nested vector here:
|
||||||
// `[(foo ?x ?y)]` or `[[foo ?x ?y]]`
|
// `[(foo ?x ?y)]` or `[[foo ?x ?y]]`
|
||||||
vector()
|
vector()
|
||||||
.of(seq()
|
.of_exactly(seq()
|
||||||
.of((Query::predicate_fn(), Query::arguments())
|
.of_exactly((Query::predicate_fn(), Query::arguments())
|
||||||
.map(|(f, args)| {
|
.map(|(f, args)| {
|
||||||
WhereClause::Pred(
|
WhereClause::Pred(
|
||||||
Predicate {
|
Predicate {
|
||||||
|
@ -225,7 +225,7 @@ def_parser!(Where, pred, WhereClause, {
|
||||||
|
|
||||||
def_parser!(Where, pattern, WhereClause, {
|
def_parser!(Where, pattern, WhereClause, {
|
||||||
vector()
|
vector()
|
||||||
.of(
|
.of_exactly(
|
||||||
// While *technically* Datomic allows you to have a query like:
|
// While *technically* Datomic allows you to have a query like:
|
||||||
// [:find … :where [[?x]]]
|
// [:find … :where [[?x]]]
|
||||||
// We don't -- we require at least e, a.
|
// We don't -- we require at least e, a.
|
||||||
|
@ -313,7 +313,7 @@ def_parser!(Find, find_scalar, FindSpec, {
|
||||||
|
|
||||||
def_parser!(Find, find_coll, FindSpec, {
|
def_parser!(Find, find_coll, FindSpec, {
|
||||||
vector()
|
vector()
|
||||||
.of(Query::variable()
|
.of_exactly(Query::variable()
|
||||||
.map(|var| FindSpec::FindColl(Element::Variable(var)))
|
.map(|var| FindSpec::FindColl(Element::Variable(var)))
|
||||||
.skip(Find::ellipsis()))
|
.skip(Find::ellipsis()))
|
||||||
});
|
});
|
||||||
|
@ -328,7 +328,7 @@ def_parser!(Find, find_rel, FindSpec, {
|
||||||
|
|
||||||
def_parser!(Find, find_tuple, FindSpec, {
|
def_parser!(Find, find_tuple, FindSpec, {
|
||||||
vector()
|
vector()
|
||||||
.of(Find::elements().map(FindSpec::FindTuple))
|
.of_exactly(Find::elements().map(FindSpec::FindTuple))
|
||||||
});
|
});
|
||||||
|
|
||||||
/// Parse a stream values into one of four find specs.
|
/// Parse a stream values into one of four find specs.
|
||||||
|
@ -395,16 +395,16 @@ enum FindQueryPart {
|
||||||
/// construct a `FindQuery` from them.
|
/// construct a `FindQuery` from them.
|
||||||
def_parser!(Find, query, FindQuery, {
|
def_parser!(Find, query, FindQuery, {
|
||||||
let p_find_spec = Find::literal_find()
|
let p_find_spec = Find::literal_find()
|
||||||
.with(vector().of(Find::spec().map(FindQueryPart::FindSpec)));
|
.with(vector().of_exactly(Find::spec().map(FindQueryPart::FindSpec)));
|
||||||
|
|
||||||
let p_with_vars = Find::literal_with()
|
let p_with_vars = Find::literal_with()
|
||||||
.with(vector().of(many(Query::variable()).map(FindQueryPart::With)));
|
.with(vector().of_exactly(many(Query::variable()).map(FindQueryPart::With)));
|
||||||
|
|
||||||
let p_where_clauses = Find::literal_where()
|
let p_where_clauses = Find::literal_where()
|
||||||
.with(vector().of(Where::clauses().map(FindQueryPart::WhereClauses))).expected(":where clauses");
|
.with(vector().of_exactly(Where::clauses().map(FindQueryPart::WhereClauses))).expected(":where clauses");
|
||||||
|
|
||||||
(or(map(), keyword_map()))
|
(or(map(), keyword_map()))
|
||||||
.of(many(choice::<[&mut Parser<Input = ValueStream, Output = FindQueryPart>; 3], _>([
|
.of_exactly(many(choice::<[&mut Parser<Input = ValueStream, Output = FindQueryPart>; 3], _>([
|
||||||
&mut try(p_find_spec),
|
&mut try(p_find_spec),
|
||||||
&mut try(p_with_vars),
|
&mut try(p_with_vars),
|
||||||
&mut try(p_where_clauses),
|
&mut try(p_where_clauses),
|
||||||
|
@ -619,7 +619,7 @@ mod test {
|
||||||
fn test_find_sp_variable() {
|
fn test_find_sp_variable() {
|
||||||
let sym = edn::PlainSymbol::new("?x");
|
let sym = edn::PlainSymbol::new("?x");
|
||||||
let input = edn::Value::Vector(vec![edn::Value::PlainSymbol(sym.clone())]);
|
let input = edn::Value::Vector(vec![edn::Value::PlainSymbol(sym.clone())]);
|
||||||
assert_parses_to!(|| vector().of(Query::variable()), input, variable(sym));
|
assert_parses_to!(|| vector().of_exactly(Query::variable()), input, variable(sym));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -627,7 +627,7 @@ mod test {
|
||||||
let sym = edn::PlainSymbol::new("?x");
|
let sym = edn::PlainSymbol::new("?x");
|
||||||
let period = edn::PlainSymbol::new(".");
|
let period = edn::PlainSymbol::new(".");
|
||||||
let input = edn::Value::Vector(vec![edn::Value::PlainSymbol(sym.clone()), edn::Value::PlainSymbol(period.clone())]);
|
let input = edn::Value::Vector(vec![edn::Value::PlainSymbol(sym.clone()), edn::Value::PlainSymbol(period.clone())]);
|
||||||
assert_parses_to!(|| vector().of(Find::find_scalar()),
|
assert_parses_to!(|| vector().of_exactly(Find::find_scalar()),
|
||||||
input,
|
input,
|
||||||
FindSpec::FindScalar(Element::Variable(variable(sym))));
|
FindSpec::FindScalar(Element::Variable(variable(sym))));
|
||||||
}
|
}
|
||||||
|
@ -648,7 +648,7 @@ mod test {
|
||||||
let vx = edn::PlainSymbol::new("?x");
|
let vx = edn::PlainSymbol::new("?x");
|
||||||
let vy = edn::PlainSymbol::new("?y");
|
let vy = edn::PlainSymbol::new("?y");
|
||||||
let input = edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(vy.clone())]);
|
let input = edn::Value::Vector(vec![edn::Value::PlainSymbol(vx.clone()), edn::Value::PlainSymbol(vy.clone())]);
|
||||||
assert_parses_to!(|| vector().of(Find::find_rel()),
|
assert_parses_to!(|| vector().of_exactly(Find::find_rel()),
|
||||||
input,
|
input,
|
||||||
FindSpec::FindRel(vec![Element::Variable(variable(vx)),
|
FindSpec::FindRel(vec![Element::Variable(variable(vx)),
|
||||||
Element::Variable(variable(vy))]));
|
Element::Variable(variable(vy))]));
|
||||||
|
|
|
@ -45,7 +45,7 @@ use mentat_tx::entities::{
|
||||||
use mentat_parser_utils::{ResultParser};
|
use mentat_parser_utils::{ResultParser};
|
||||||
use mentat_parser_utils::value_and_span::{
|
use mentat_parser_utils::value_and_span::{
|
||||||
Item,
|
Item,
|
||||||
OfParsing,
|
OfExactlyParsing,
|
||||||
integer,
|
integer,
|
||||||
list,
|
list,
|
||||||
map,
|
map,
|
||||||
|
@ -66,8 +66,8 @@ def_parser!(Tx, entid, Entid, {
|
||||||
});
|
});
|
||||||
|
|
||||||
def_parser!(Tx, lookup_ref, LookupRef, {
|
def_parser!(Tx, lookup_ref, LookupRef, {
|
||||||
list()
|
list().of_exactly(
|
||||||
.of(value(edn::Value::PlainSymbol(PlainSymbol::new("lookup-ref")))
|
value(edn::Value::PlainSymbol(PlainSymbol::new("lookup-ref")))
|
||||||
.with((Tx::entid(),
|
.with((Tx::entid(),
|
||||||
Tx::atom()))
|
Tx::atom()))
|
||||||
.map(|(a, v)| LookupRef { a: a, v: v.without_spans() }))
|
.map(|(a, v)| LookupRef { a: a, v: v.without_spans() }))
|
||||||
|
@ -88,7 +88,7 @@ def_parser!(Tx, atom, edn::ValueAndSpan, {
|
||||||
});
|
});
|
||||||
|
|
||||||
def_parser!(Tx, nested_vector, Vec<AtomOrLookupRefOrVectorOrMapNotation>, {
|
def_parser!(Tx, nested_vector, Vec<AtomOrLookupRefOrVectorOrMapNotation>, {
|
||||||
vector().of(many(Tx::atom_or_lookup_ref_or_vector()))
|
vector().of_exactly(many(Tx::atom_or_lookup_ref_or_vector()))
|
||||||
});
|
});
|
||||||
|
|
||||||
def_parser!(Tx, atom_or_lookup_ref_or_vector, AtomOrLookupRefOrVectorOrMapNotation, {
|
def_parser!(Tx, atom_or_lookup_ref_or_vector, AtomOrLookupRefOrVectorOrMapNotation, {
|
||||||
|
@ -116,12 +116,12 @@ def_parser!(Tx, add_or_retract, Entity, {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
vector().of(p)
|
vector().of_exactly(p)
|
||||||
});
|
});
|
||||||
|
|
||||||
def_parser!(Tx, map_notation, MapNotation, {
|
def_parser!(Tx, map_notation, MapNotation, {
|
||||||
map()
|
map()
|
||||||
.of(many((Tx::entid(), Tx::atom_or_lookup_ref_or_vector())))
|
.of_exactly(many((Tx::entid(), Tx::atom_or_lookup_ref_or_vector())))
|
||||||
.map(|avs: Vec<(Entid, AtomOrLookupRefOrVectorOrMapNotation)>| -> MapNotation {
|
.map(|avs: Vec<(Entid, AtomOrLookupRefOrVectorOrMapNotation)>| -> MapNotation {
|
||||||
avs.into_iter().collect()
|
avs.into_iter().collect()
|
||||||
})
|
})
|
||||||
|
@ -133,7 +133,7 @@ def_parser!(Tx, entity, Entity, {
|
||||||
});
|
});
|
||||||
|
|
||||||
def_parser!(Tx, entities, Vec<Entity>, {
|
def_parser!(Tx, entities, Vec<Entity>, {
|
||||||
vector().of(many(Tx::entity()))
|
vector().of_exactly(many(Tx::entity()))
|
||||||
});
|
});
|
||||||
|
|
||||||
impl Tx {
|
impl Tx {
|
||||||
|
@ -185,7 +185,9 @@ pub fn remove_db_id(map: &mut MapNotation) -> std::result::Result<Option<EntidOr
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use std::collections::LinkedList;
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
use combine::Parser;
|
use combine::Parser;
|
||||||
use edn::symbols::NamespacedKeyword;
|
use edn::symbols::NamespacedKeyword;
|
||||||
use edn::{
|
use edn::{
|
||||||
|
@ -198,11 +200,9 @@ mod tests {
|
||||||
Entid,
|
Entid,
|
||||||
EntidOrLookupRefOrTempId,
|
EntidOrLookupRefOrTempId,
|
||||||
Entity,
|
Entity,
|
||||||
LookupRef,
|
|
||||||
OpType,
|
OpType,
|
||||||
AtomOrLookupRefOrVectorOrMapNotation,
|
AtomOrLookupRefOrVectorOrMapNotation,
|
||||||
};
|
};
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
fn kw(namespace: &str, name: &str) -> Value {
|
fn kw(namespace: &str, name: &str) -> Value {
|
||||||
Value::NamespacedKeyword(NamespacedKeyword::new(namespace, name))
|
Value::NamespacedKeyword(NamespacedKeyword::new(namespace, name))
|
||||||
|
@ -213,9 +213,9 @@ mod tests {
|
||||||
let input = Value::Vector(vec![kw("db", "add"),
|
let input = Value::Vector(vec![kw("db", "add"),
|
||||||
kw("test", "entid"),
|
kw("test", "entid"),
|
||||||
kw("test", "a"),
|
kw("test", "a"),
|
||||||
Value::Text("v".into())]).with_spans();
|
Value::Text("v".into())]);
|
||||||
let mut parser = Tx::entity();
|
let mut parser = Tx::entity();
|
||||||
let result = parser.parse(input.into_atom_stream()).map(|x| x.0);
|
let result = parser.parse(input.with_spans().into_atom_stream()).map(|x| x.0);
|
||||||
assert_eq!(result,
|
assert_eq!(result,
|
||||||
Ok(Entity::AddOrRetract {
|
Ok(Entity::AddOrRetract {
|
||||||
op: OpType::Add,
|
op: OpType::Add,
|
||||||
|
@ -226,91 +226,82 @@ mod tests {
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn test_retract() {
|
fn test_retract() {
|
||||||
// let input = [Value::Vector(vec![kw("db", "retract"),
|
let input = Value::Vector(vec![kw("db", "retract"),
|
||||||
// Value::Integer(101),
|
Value::Integer(101),
|
||||||
// kw("test", "a"),
|
kw("test", "a"),
|
||||||
// Value::Text("v".into())])];
|
Value::Text("v".into())]);
|
||||||
// let mut parser = Tx::entity();
|
let mut parser = Tx::entity();
|
||||||
// let result = parser.parse(&input[..]);
|
let result = parser.parse(input.with_spans().into_atom_stream()).map(|x| x.0);
|
||||||
// assert_eq!(result,
|
assert_eq!(result,
|
||||||
// Ok((Entity::AddOrRetract {
|
Ok(Entity::AddOrRetract {
|
||||||
// op: OpType::Retract,
|
op: OpType::Retract,
|
||||||
// e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(101)),
|
e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(101)),
|
||||||
// a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
||||||
// v: AtomOrLookupRefOrVectorOrMapNotation::Atom(Value::Text("v".into())),
|
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("v".into()), Span(25, 28))),
|
||||||
// },
|
}));
|
||||||
// &[][..])));
|
}
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn test_lookup_ref() {
|
fn test_lookup_ref() {
|
||||||
// let mut list = LinkedList::new();
|
let input = Value::Vector(vec![kw("db", "add"),
|
||||||
// list.push_back(Value::PlainSymbol(PlainSymbol::new("lookup-ref")));
|
Value::List(vec![Value::PlainSymbol(PlainSymbol::new("lookup-ref")),
|
||||||
// list.push_back(kw("test", "a1"));
|
kw("test", "a1"),
|
||||||
// list.push_back(Value::Text("v1".into()));
|
Value::Text("v1".into())].into_iter().collect()),
|
||||||
|
kw("test", "a"),
|
||||||
|
Value::Text("v".into())]);
|
||||||
|
let mut parser = Tx::entity();
|
||||||
|
let result = parser.parse(input.with_spans().into_atom_stream()).map(|x| x.0);
|
||||||
|
assert_eq!(result,
|
||||||
|
Ok(Entity::AddOrRetract {
|
||||||
|
op: OpType::Add,
|
||||||
|
e: EntidOrLookupRefOrTempId::LookupRef(LookupRef {
|
||||||
|
a: Entid::Ident(NamespacedKeyword::new("test", "a1")),
|
||||||
|
v: Value::Text("v1".into()),
|
||||||
|
}),
|
||||||
|
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
||||||
|
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("v".into()), Span(44, 47))),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// let input = [Value::Vector(vec![kw("db", "add"),
|
#[test]
|
||||||
// Value::List(list),
|
fn test_nested_vector() {
|
||||||
// kw("test", "a"),
|
let input = Value::Vector(vec![kw("db", "add"),
|
||||||
// Value::Text("v".into())])];
|
Value::List(vec![Value::PlainSymbol(PlainSymbol::new("lookup-ref")),
|
||||||
// let mut parser = Tx::entity();
|
kw("test", "a1"),
|
||||||
// let result = parser.parse(&input[..]);
|
Value::Text("v1".into())].into_iter().collect()),
|
||||||
// assert_eq!(result,
|
kw("test", "a"),
|
||||||
// Ok((Entity::AddOrRetract {
|
Value::Vector(vec![Value::Text("v1".into()), Value::Text("v2".into())])]);
|
||||||
// op: OpType::Add,
|
let mut parser = Tx::entity();
|
||||||
// e: EntidOrLookupRefOrTempId::LookupRef(LookupRef {
|
let result = parser.parse(input.with_spans().into_atom_stream()).map(|x| x.0);
|
||||||
// a: Entid::Ident(NamespacedKeyword::new("test", "a1")),
|
assert_eq!(result,
|
||||||
// v: Value::Text("v1".into()),
|
Ok(Entity::AddOrRetract {
|
||||||
// }),
|
op: OpType::Add,
|
||||||
// a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
e: EntidOrLookupRefOrTempId::LookupRef(LookupRef {
|
||||||
// v: AtomOrLookupRefOrVectorOrMapNotation::Atom(Value::Text("v".into())),
|
a: Entid::Ident(NamespacedKeyword::new("test", "a1")),
|
||||||
// },
|
v: Value::Text("v1".into()),
|
||||||
// &[][..])));
|
}),
|
||||||
// }
|
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
||||||
|
v: AtomOrLookupRefOrVectorOrMapNotation::Vector(vec![AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("v1".into()), Span(45, 49))),
|
||||||
|
AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("v2".into()), Span(50, 54)))]),
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
// #[test]
|
#[test]
|
||||||
// fn test_nested_vector() {
|
fn test_map_notation() {
|
||||||
// let mut list = LinkedList::new();
|
let mut expected: MapNotation = BTreeMap::default();
|
||||||
// list.push_back(Value::PlainSymbol(PlainSymbol::new("lookup-ref")));
|
expected.insert(Entid::Ident(NamespacedKeyword::new("db", "id")), AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("t".to_string()), Span(8, 11))));
|
||||||
// list.push_back(kw("test", "a1"));
|
expected.insert(Entid::Ident(NamespacedKeyword::new("db", "ident")), AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::NamespacedKeyword(NamespacedKeyword::new("test", "attribute")), Span(22, 37))));
|
||||||
// list.push_back(Value::Text("v1".into()));
|
|
||||||
|
|
||||||
// let input = [Value::Vector(vec![kw("db", "add"),
|
let mut map: BTreeMap<Value, Value> = BTreeMap::default();
|
||||||
// Value::List(list),
|
map.insert(kw("db", "id"), Value::Text("t".to_string()));
|
||||||
// kw("test", "a"),
|
map.insert(kw("db", "ident"), kw("test", "attribute"));
|
||||||
// Value::Vector(vec![Value::Text("v1".into()), Value::Text("v2".into())])])];
|
let input = Value::Map(map.clone());
|
||||||
// let mut parser = Tx::entity();
|
|
||||||
// let result = parser.parse(&input[..]);
|
|
||||||
// assert_eq!(result,
|
|
||||||
// Ok((Entity::AddOrRetract {
|
|
||||||
// op: OpType::Add,
|
|
||||||
// e: EntidOrLookupRefOrTempId::LookupRef(LookupRef {
|
|
||||||
// a: Entid::Ident(NamespacedKeyword::new("test", "a1")),
|
|
||||||
// v: Value::Text("v1".into()),
|
|
||||||
// }),
|
|
||||||
// a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
|
||||||
// v: AtomOrLookupRefOrVectorOrMapNotation::Vector(vec![AtomOrLookupRefOrVectorOrMapNotation::Atom(Value::Text("v1".into())),
|
|
||||||
// AtomOrLookupRefOrVectorOrMapNotation::Atom(Value::Text("v2".into()))]),
|
|
||||||
// },
|
|
||||||
// &[][..])));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// #[test]
|
let mut parser = Tx::entity();
|
||||||
// fn test_map_notation() {
|
let result = parser.parse(input.with_spans().into_atom_stream()).map(|x| x.0);
|
||||||
// let mut expected: MapNotation = BTreeMap::default();
|
assert_eq!(result,
|
||||||
// expected.insert(Entid::Ident(NamespacedKeyword::new("db", "id")), AtomOrLookupRefOrVectorOrMapNotation::Atom(Value::Text("t".to_string())));
|
Ok(Entity::MapNotation(expected)));
|
||||||
// expected.insert(Entid::Ident(NamespacedKeyword::new("db", "ident")), AtomOrLookupRefOrVectorOrMapNotation::Atom(kw("test", "attribute")));
|
}
|
||||||
|
|
||||||
// let mut map: BTreeMap<Value, Value> = BTreeMap::default();
|
|
||||||
// map.insert(kw("db", "id"), Value::Text("t".to_string()));
|
|
||||||
// map.insert(kw("db", "ident"), kw("test", "attribute"));
|
|
||||||
// let input = [Value::Map(map.clone())];
|
|
||||||
// let mut parser = Tx::entity();
|
|
||||||
// let result = parser.parse(&input[..]);
|
|
||||||
// assert_eq!(result,
|
|
||||||
// Ok((Entity::MapNotation(expected),
|
|
||||||
// &[][..])));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue