Post: Remove tx-parser crate entirely.
This commit is contained in:
parent
cbffe5e545
commit
7a8c9d90c2
8 changed files with 0 additions and 668 deletions
|
@ -76,9 +76,6 @@ path = "query-translator"
|
||||||
[dependencies.mentat_tx]
|
[dependencies.mentat_tx]
|
||||||
path = "tx"
|
path = "tx"
|
||||||
|
|
||||||
[dependencies.mentat_tx_parser]
|
|
||||||
path = "tx-parser"
|
|
||||||
|
|
||||||
[dependencies.mentat_tolstoy]
|
[dependencies.mentat_tolstoy]
|
||||||
path = "tolstoy"
|
path = "tolstoy"
|
||||||
|
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "mentat_tx_parser"
|
|
||||||
version = "0.0.1"
|
|
||||||
workspace = ".."
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
combine = "2.3.2"
|
|
||||||
error-chain = { git = "https://github.com/rnewman/error-chain", branch = "rnewman/sync" }
|
|
||||||
|
|
||||||
[dependencies.edn]
|
|
||||||
path = "../edn"
|
|
||||||
|
|
||||||
[dependencies.mentat_tx]
|
|
||||||
path = "../tx"
|
|
||||||
|
|
||||||
[dependencies.mentat_parser_utils]
|
|
||||||
path = "../parser-utils"
|
|
|
@ -1,81 +0,0 @@
|
||||||
Before slices, release:
|
|
||||||
|
|
||||||
⋊> ~/M/mentat on ⨯ cargo bench --package mentat_tx_parser
|
|
||||||
Finished release [optimized] target(s) in 0.0 secs
|
|
||||||
Running target/release/deps/bench-0defa345d586a763
|
|
||||||
|
|
||||||
running 2 tests
|
|
||||||
test bench_parse1 ... bench: 7,745 ns/iter (+/- 2,515)
|
|
||||||
test bench_parse2 ... bench: 494,244 ns/iter (+/- 159,379)
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured
|
|
||||||
|
|
||||||
Running target/release/deps/mentat_tx_parser-c3f614f12d05a17a
|
|
||||||
|
|
||||||
running 5 tests
|
|
||||||
test tests::test_add ... ignored
|
|
||||||
test tests::test_lookup_ref ... ignored
|
|
||||||
test tests::test_map_notation ... ignored
|
|
||||||
test tests::test_nested_vector ... ignored
|
|
||||||
test tests::test_retract ... ignored
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 5 ignored; 0 measured
|
|
||||||
|
|
||||||
⋊> ~/M/mentat on ⨯ cargo bench --package mentat_tx_parser
|
|
||||||
Finished release [optimized] target(s) in 0.0 secs
|
|
||||||
Running target/release/deps/bench-0defa345d586a763
|
|
||||||
|
|
||||||
running 2 tests
|
|
||||||
test bench_parse1 ... bench: 7,793 ns/iter (+/- 1,258)
|
|
||||||
test bench_parse2 ... bench: 532,144 ns/iter (+/- 110,614)
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 2 measured
|
|
||||||
|
|
||||||
After slices, release:
|
|
||||||
|
|
||||||
⋊> ~/M/mentat on parse-faster ⨯ cargo bench --package mentat_tx_parser 16:10:57
|
|
||||||
Compiling mentat_tx_parser v0.0.1 (file:///Users/nalexander/Mozilla/mentat/tx-parser)
|
|
||||||
Finished release [optimized + debuginfo] target(s) in 2.25 secs
|
|
||||||
Running target/release/deps/bench-0defa345d586a763
|
|
||||||
|
|
||||||
running 3 tests
|
|
||||||
test bench_parse1 ... bench: 1,413 ns/iter (+/- 92)
|
|
||||||
test bench_parse2 ... bench: 26,190 ns/iter (+/- 4,167)
|
|
||||||
test bench_parse3 ... bench: 51,823 ns/iter (+/- 7,000)
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured
|
|
||||||
|
|
||||||
Running target/release/deps/mentat_tx_parser-c3f614f12d05a17a
|
|
||||||
|
|
||||||
running 1 test
|
|
||||||
test tests::test_add ... ignored
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured
|
|
||||||
|
|
||||||
⋊> ~/M/mentat on parse-faster ⨯ cargo bench --package mentat_tx_parser 16:16:35
|
|
||||||
Finished release [optimized + debuginfo] target(s) in 0.0 secs
|
|
||||||
Running target/release/deps/bench-0defa345d586a763
|
|
||||||
|
|
||||||
running 3 tests
|
|
||||||
test bench_parse1 ... bench: 1,410 ns/iter (+/- 164)
|
|
||||||
test bench_parse2 ... bench: 26,195 ns/iter (+/- 1,851)
|
|
||||||
test bench_parse3 ... bench: 51,680 ns/iter (+/- 12,190)
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured
|
|
||||||
|
|
||||||
Running target/release/deps/mentat_tx_parser-c3f614f12d05a17a
|
|
||||||
|
|
||||||
running 1 test
|
|
||||||
test tests::test_add ... ignored
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 1 ignored; 0 measured
|
|
||||||
|
|
||||||
test bench_parse1 ... bench: 7,690 ns/iter (+/- 3,035)
|
|
||||||
test bench_parse2 ... bench: 548,920 ns/iter (+/- 282,846)
|
|
||||||
test bench_parse3 ... bench: 1,757,897 ns/iter (+/- 301,719)
|
|
||||||
test bench_parse4 ... bench: 6,957,627 ns/iter (+/- 1,162,660)
|
|
||||||
|
|
||||||
test bench_parse1 ... bench: 1,038 ns/iter (+/- 213)
|
|
||||||
test bench_parse2 ... bench: 18,647 ns/iter (+/- 3,971)
|
|
||||||
test bench_parse3 ... bench: 36,715 ns/iter (+/- 6,508)
|
|
||||||
test bench_parse4 ... bench: 79,502 ns/iter (+/- 19,525)
|
|
|
@ -1,87 +0,0 @@
|
||||||
#![feature(test)]
|
|
||||||
|
|
||||||
// These benchmarks can be run from the project root with:
|
|
||||||
// > cargo bench --package mentat_tx_parser
|
|
||||||
|
|
||||||
extern crate test;
|
|
||||||
extern crate edn;
|
|
||||||
extern crate mentat_tx_parser;
|
|
||||||
|
|
||||||
use test::Bencher;
|
|
||||||
use mentat_tx_parser::Tx;
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_parse1(b: &mut Bencher) {
|
|
||||||
let input = r#"[[:db/add 1 :test/val "a"]]"#;
|
|
||||||
let parsed_edn = edn::parse::value(input).expect("to parse test input");
|
|
||||||
b.iter(|| Tx::parse(&parsed_edn));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_parse2(b: &mut Bencher) {
|
|
||||||
let input = r#"
|
|
||||||
[[:db/add 1 :test/val "a"]
|
|
||||||
[:db/add 2 :test/val "b"]
|
|
||||||
[:db/add 3 :test/val "c"]
|
|
||||||
[:db/add 4 :test/val "d"]
|
|
||||||
[:db/add 5 :test/val "e"]
|
|
||||||
[:db/add 6 :test/val "f"]
|
|
||||||
[:db/add 7 :test/val "g"]
|
|
||||||
[:db/add 8 :test/val "h"]
|
|
||||||
[:db/add 9 :test/val "i"]
|
|
||||||
[:db/add 10 :test/val "j"]
|
|
||||||
[:db/add 11 :test/val "k"]
|
|
||||||
[:db/add 12 :test/val "l"]
|
|
||||||
[:db/add 13 :test/val "m"]
|
|
||||||
[:db/add 14 :test/val "n"]
|
|
||||||
[:db/add 15 :test/val "o"]
|
|
||||||
[:db/add 16 :test/val "p"]
|
|
||||||
[:db/add 17 :test/val "q"]
|
|
||||||
[:db/add 18 :test/val "r"]
|
|
||||||
[:db/add 19 :test/val "s"]
|
|
||||||
[:db/add 20 :test/val "t"]
|
|
||||||
[:db/add 21 :test/val "u"]
|
|
||||||
[:db/add 22 :test/val "v"]
|
|
||||||
[:db/add 23 :test/val "w"]
|
|
||||||
[:db/add 24 :test/val "x"]
|
|
||||||
[:db/add 25 :test/val "y"]
|
|
||||||
[:db/add 26 :test/val "z"]]"#;
|
|
||||||
b.iter(|| {
|
|
||||||
let parsed_edn = edn::parse::value(input).expect("to parse test input");
|
|
||||||
Tx::parse(&parsed_edn).expect("to parse tx");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[bench]
|
|
||||||
fn bench_parse3(b: &mut Bencher) {
|
|
||||||
let input = r#"
|
|
||||||
[[:db/add 1 :test/val "a"]
|
|
||||||
[:db/add 2 :test/val "b"]
|
|
||||||
[:db/add 3 :test/val "c"]
|
|
||||||
[:db/add 4 :test/val "d"]
|
|
||||||
[:db/add 5 :test/val "e"]
|
|
||||||
[:db/add 6 :test/val "f"]
|
|
||||||
[:db/add 7 :test/val "g"]
|
|
||||||
[:db/add 8 :test/val "h"]
|
|
||||||
[:db/add 9 :test/val "i"]
|
|
||||||
[:db/add 10 :test/val "j"]
|
|
||||||
[:db/add 11 :test/val "k"]
|
|
||||||
[:db/add 12 :test/val "l"]
|
|
||||||
[:db/add 13 :test/val "m"]
|
|
||||||
[:db/add 14 :test/val "n"]
|
|
||||||
[:db/add 15 :test/val "o"]
|
|
||||||
[:db/add 16 :test/val "p"]
|
|
||||||
[:db/add 17 :test/val "q"]
|
|
||||||
[:db/add 18 :test/val "r"]
|
|
||||||
[:db/add 19 :test/val "s"]
|
|
||||||
[:db/add 20 :test/val "t"]
|
|
||||||
[:db/add 21 :test/val "u"]
|
|
||||||
[:db/add 22 :test/val "v"]
|
|
||||||
[:db/add 23 :test/val "w"]
|
|
||||||
[:db/add 24 :test/val "x"]
|
|
||||||
[:db/add 25 :test/val "y"]
|
|
||||||
[:db/add 26 :test/val "z"]]"#;
|
|
||||||
b.iter(|| {
|
|
||||||
edn::parse::entities(input).expect("to parse test input");
|
|
||||||
});
|
|
||||||
}
|
|
|
@ -1,17 +0,0 @@
|
||||||
|
|
||||||
running 5 tests
|
|
||||||
test tests::test_add ... ignored
|
|
||||||
test tests::test_lookup_ref ... ignored
|
|
||||||
test tests::test_map_notation ... ignored
|
|
||||||
test tests::test_nested_vector ... ignored
|
|
||||||
test tests::test_retract ... ignored
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 5 ignored; 0 measured; 0 filtered out
|
|
||||||
|
|
||||||
|
|
||||||
running 3 tests
|
|
||||||
test bench_parse1 ... bench: 2,799 ns/iter (+/- 801)
|
|
||||||
test bench_parse2 ... bench: 191,856 ns/iter (+/- 19,331)
|
|
||||||
test bench_parse3 ... bench: 53,925 ns/iter (+/- 10,299)
|
|
||||||
|
|
||||||
test result: ok. 0 passed; 0 failed; 0 ignored; 3 measured; 0 filtered out
|
|
|
@ -1,31 +0,0 @@
|
||||||
// Copyright 2016 Mozilla
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
// this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
// License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
use mentat_parser_utils::ValueParseError;
|
|
||||||
|
|
||||||
error_chain! {
|
|
||||||
types {
|
|
||||||
Error, ErrorKind, ResultExt, Result;
|
|
||||||
}
|
|
||||||
|
|
||||||
errors {
|
|
||||||
ParseError(parse_error: ValueParseError) {
|
|
||||||
description("error parsing edn values")
|
|
||||||
display("error parsing edn values:\n{}", parse_error)
|
|
||||||
}
|
|
||||||
|
|
||||||
DbIdError {
|
|
||||||
description("bad :db/id in map notation")
|
|
||||||
display("bad :db/id in map notation: must either be not present or be an entid, an ident, or a tempid")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,326 +0,0 @@
|
||||||
// Copyright 2016 Mozilla
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
// this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
// License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
#![allow(dead_code)]
|
|
||||||
|
|
||||||
extern crate combine;
|
|
||||||
#[macro_use]
|
|
||||||
extern crate error_chain;
|
|
||||||
|
|
||||||
extern crate edn;
|
|
||||||
extern crate mentat_tx;
|
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate mentat_parser_utils;
|
|
||||||
|
|
||||||
use combine::{
|
|
||||||
choice,
|
|
||||||
eof,
|
|
||||||
many,
|
|
||||||
parser,
|
|
||||||
satisfy,
|
|
||||||
satisfy_map,
|
|
||||||
try,
|
|
||||||
Parser,
|
|
||||||
ParseResult,
|
|
||||||
};
|
|
||||||
use mentat_tx::entities::{
|
|
||||||
AtomOrLookupRefOrVectorOrMapNotation,
|
|
||||||
Entid,
|
|
||||||
EntidOrLookupRefOrTempId,
|
|
||||||
Entity,
|
|
||||||
LookupRef,
|
|
||||||
MapNotation,
|
|
||||||
OpType,
|
|
||||||
TempId,
|
|
||||||
TxFunction,
|
|
||||||
};
|
|
||||||
use mentat_parser_utils::{ResultParser};
|
|
||||||
use mentat_parser_utils::value_and_span::{
|
|
||||||
Item,
|
|
||||||
OfExactlyParsing,
|
|
||||||
backward_keyword,
|
|
||||||
forward_keyword,
|
|
||||||
integer,
|
|
||||||
list,
|
|
||||||
map,
|
|
||||||
namespaced_keyword,
|
|
||||||
vector,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub mod errors;
|
|
||||||
pub use errors::*;
|
|
||||||
|
|
||||||
pub struct Tx<'a>(std::marker::PhantomData<&'a ()>);
|
|
||||||
|
|
||||||
// Accepts entid, :attribute/forward, and :attribute/_backward.
|
|
||||||
def_parser!(Tx, entid, Entid, {
|
|
||||||
integer()
|
|
||||||
.map(|x| Entid::Entid(x))
|
|
||||||
.or(namespaced_keyword().map(|x| Entid::Ident(x.clone())))
|
|
||||||
});
|
|
||||||
|
|
||||||
// Accepts entid and :attribute/forward.
|
|
||||||
def_parser!(Tx, forward_entid, Entid, {
|
|
||||||
integer()
|
|
||||||
.map(|x| Entid::Entid(x))
|
|
||||||
.or(forward_keyword().map(|x| Entid::Ident(x.clone())))
|
|
||||||
});
|
|
||||||
|
|
||||||
// Accepts only :attribute/_backward.
|
|
||||||
def_parser!(Tx, backward_entid, Entid, {
|
|
||||||
backward_keyword().map(|x| Entid::Ident(x.to_reversed()))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_matches_plain_symbol!(Tx, literal_lookup_ref, "lookup-ref");
|
|
||||||
|
|
||||||
def_parser!(Tx, lookup_ref, LookupRef, {
|
|
||||||
list().of_exactly(
|
|
||||||
Tx::literal_lookup_ref()
|
|
||||||
.with((Tx::entid(),
|
|
||||||
Tx::atom()))
|
|
||||||
.map(|(a, v)| LookupRef { a: a, v: v.clone().without_spans() }))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, entid_or_lookup_ref_or_temp_id, EntidOrLookupRefOrTempId, {
|
|
||||||
Tx::temp_id().map(EntidOrLookupRefOrTempId::TempId)
|
|
||||||
.or(Tx::entid().map(EntidOrLookupRefOrTempId::Entid))
|
|
||||||
.or(try(Tx::lookup_ref().map(EntidOrLookupRefOrTempId::LookupRef)))
|
|
||||||
.or(try(Tx::tx_function().map(EntidOrLookupRefOrTempId::TxFunction)))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_matches_plain_symbol!(Tx, literal_transaction_tx, "transaction-tx");
|
|
||||||
|
|
||||||
def_parser!(Tx, tx_function, TxFunction, {
|
|
||||||
list().of_exactly(
|
|
||||||
Tx::literal_transaction_tx().map(|_| edn::PlainSymbol::new("transaction-tx"))
|
|
||||||
.map(|op| TxFunction { op: op }))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, temp_id, TempId, {
|
|
||||||
satisfy_map(|x: &'a edn::ValueAndSpan| x.as_text().cloned().map(TempId::External))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, atom, &'a edn::ValueAndSpan, {
|
|
||||||
satisfy_map(|x: &'a edn::ValueAndSpan| x.as_atom())
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, nested_vector, Vec<AtomOrLookupRefOrVectorOrMapNotation>, {
|
|
||||||
vector().of_exactly(many(Tx::atom_or_lookup_ref_or_vector()))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, atom_or_lookup_ref_or_vector, AtomOrLookupRefOrVectorOrMapNotation, {
|
|
||||||
choice::<[&mut Parser<Input = _, Output = AtomOrLookupRefOrVectorOrMapNotation>; 5], _>
|
|
||||||
([&mut try(Tx::lookup_ref().map(AtomOrLookupRefOrVectorOrMapNotation::LookupRef)),
|
|
||||||
&mut try(Tx::tx_function().map(AtomOrLookupRefOrVectorOrMapNotation::TxFunction)),
|
|
||||||
&mut Tx::nested_vector().map(AtomOrLookupRefOrVectorOrMapNotation::Vector),
|
|
||||||
&mut Tx::map_notation().map(AtomOrLookupRefOrVectorOrMapNotation::MapNotation),
|
|
||||||
&mut Tx::atom().map(|x| x.clone()).map(AtomOrLookupRefOrVectorOrMapNotation::Atom)
|
|
||||||
])
|
|
||||||
});
|
|
||||||
|
|
||||||
def_matches_namespaced_keyword!(Tx, literal_db_add, "db", "add");
|
|
||||||
|
|
||||||
def_matches_namespaced_keyword!(Tx, literal_db_retract, "db", "retract");
|
|
||||||
|
|
||||||
def_parser!(Tx, add_or_retract, Entity, {
|
|
||||||
vector().of_exactly(
|
|
||||||
// TODO: This commits as soon as it sees :db/{add,retract}, but could use an improved error message.
|
|
||||||
(Tx::literal_db_add().map(|_| OpType::Add).or(Tx::literal_db_retract().map(|_| OpType::Retract)),
|
|
||||||
try((Tx::entid_or_lookup_ref_or_temp_id(),
|
|
||||||
Tx::forward_entid(),
|
|
||||||
Tx::atom_or_lookup_ref_or_vector()))
|
|
||||||
.or(try((Tx::atom_or_lookup_ref_or_vector(),
|
|
||||||
Tx::backward_entid(),
|
|
||||||
Tx::entid_or_lookup_ref_or_temp_id()))
|
|
||||||
.map(|(v, a, e)| (e, a, v))))
|
|
||||||
.map(|(op, (e, a, v))| {
|
|
||||||
Entity::AddOrRetract {
|
|
||||||
op: op,
|
|
||||||
e: e,
|
|
||||||
a: a,
|
|
||||||
v: v,
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, map_notation, MapNotation, {
|
|
||||||
map()
|
|
||||||
.of_exactly(many((Tx::entid(), Tx::atom_or_lookup_ref_or_vector())))
|
|
||||||
.map(|avs: Vec<(Entid, AtomOrLookupRefOrVectorOrMapNotation)>| -> MapNotation {
|
|
||||||
avs.into_iter().collect()
|
|
||||||
})
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, entity, Entity, {
|
|
||||||
Tx::add_or_retract()
|
|
||||||
.or(Tx::map_notation().map(Entity::MapNotation))
|
|
||||||
});
|
|
||||||
|
|
||||||
def_parser!(Tx, entities, Vec<Entity>, {
|
|
||||||
vector().of_exactly(many(Tx::entity()))
|
|
||||||
});
|
|
||||||
|
|
||||||
impl<'a> Tx<'a> {
|
|
||||||
pub fn parse(input: &'a edn::ValueAndSpan) -> std::result::Result<Vec<Entity>, errors::Error> {
|
|
||||||
Tx::entities()
|
|
||||||
.skip(eof())
|
|
||||||
.parse(input.atom_stream())
|
|
||||||
.map(|x| x.0)
|
|
||||||
.map_err(|e| Error::from_kind(ErrorKind::ParseError(e.into())))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn parse_entid_or_lookup_ref_or_temp_id(input: edn::ValueAndSpan) -> std::result::Result<EntidOrLookupRefOrTempId, errors::Error> {
|
|
||||||
Tx::entid_or_lookup_ref_or_temp_id()
|
|
||||||
.skip(eof())
|
|
||||||
.parse(input.atom_stream())
|
|
||||||
.map(|x| x.0)
|
|
||||||
.map_err(|e| Error::from_kind(ErrorKind::ParseError(e.into())))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
|
||||||
|
|
||||||
use combine::Parser;
|
|
||||||
use edn::{
|
|
||||||
NamespacedKeyword,
|
|
||||||
PlainSymbol,
|
|
||||||
Span,
|
|
||||||
SpannedValue,
|
|
||||||
Value,
|
|
||||||
ValueAndSpan,
|
|
||||||
};
|
|
||||||
use mentat_tx::entities::{
|
|
||||||
Entid,
|
|
||||||
EntidOrLookupRefOrTempId,
|
|
||||||
Entity,
|
|
||||||
OpType,
|
|
||||||
AtomOrLookupRefOrVectorOrMapNotation,
|
|
||||||
};
|
|
||||||
|
|
||||||
fn kw(namespace: &str, name: &str) -> Value {
|
|
||||||
Value::NamespacedKeyword(NamespacedKeyword::new(namespace, name))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_add() {
|
|
||||||
let input = Value::Vector(vec![kw("db", "add"),
|
|
||||||
kw("test", "entid"),
|
|
||||||
kw("test", "a"),
|
|
||||||
Value::Text("v".into())]);
|
|
||||||
|
|
||||||
let input = input.with_spans();
|
|
||||||
let stream = input.atom_stream();
|
|
||||||
let result = Tx::entity().parse(stream).map(|x| x.0);
|
|
||||||
|
|
||||||
assert_eq!(result,
|
|
||||||
Ok(Entity::AddOrRetract {
|
|
||||||
op: OpType::Add,
|
|
||||||
e: EntidOrLookupRefOrTempId::Entid(Entid::Ident(NamespacedKeyword::new("test",
|
|
||||||
"entid"))),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("v".into()), Span(29, 32))),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_retract() {
|
|
||||||
let input = Value::Vector(vec![kw("db", "retract"),
|
|
||||||
Value::Integer(101),
|
|
||||||
kw("test", "a"),
|
|
||||||
Value::Text("v".into())]);
|
|
||||||
|
|
||||||
let input = input.with_spans();
|
|
||||||
let stream = input.atom_stream();
|
|
||||||
let result = Tx::entity().parse(stream).map(|x| x.0);
|
|
||||||
|
|
||||||
assert_eq!(result,
|
|
||||||
Ok(Entity::AddOrRetract {
|
|
||||||
op: OpType::Retract,
|
|
||||||
e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(101)),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("v".into()), Span(25, 28))),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_lookup_ref() {
|
|
||||||
let input = Value::Vector(vec![kw("db", "add"),
|
|
||||||
Value::List(vec![Value::PlainSymbol(PlainSymbol::new("lookup-ref")),
|
|
||||||
kw("test", "a1"),
|
|
||||||
Value::Text("v1".into())].into_iter().collect()),
|
|
||||||
kw("test", "a"),
|
|
||||||
Value::Text("v".into())]);
|
|
||||||
|
|
||||||
let input = input.with_spans();
|
|
||||||
let stream = input.atom_stream();
|
|
||||||
let result = Tx::entity().parse(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))),
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_nested_vector() {
|
|
||||||
let input = Value::Vector(vec![kw("db", "add"),
|
|
||||||
Value::List(vec![Value::PlainSymbol(PlainSymbol::new("lookup-ref")),
|
|
||||||
kw("test", "a1"),
|
|
||||||
Value::Text("v1".into())].into_iter().collect()),
|
|
||||||
kw("test", "a"),
|
|
||||||
Value::Vector(vec![Value::Text("v1".into()), Value::Text("v2".into())])]);
|
|
||||||
|
|
||||||
let input = input.with_spans();
|
|
||||||
let stream = input.atom_stream();
|
|
||||||
let result = Tx::entity().parse(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::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]
|
|
||||||
fn test_map_notation() {
|
|
||||||
let mut expected: MapNotation = BTreeMap::default();
|
|
||||||
expected.insert(Entid::Ident(NamespacedKeyword::new("db", "id")), AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::Text("t".to_string()), Span(8, 11))));
|
|
||||||
expected.insert(Entid::Ident(NamespacedKeyword::new("db", "ident")), AtomOrLookupRefOrVectorOrMapNotation::Atom(ValueAndSpan::new(SpannedValue::NamespacedKeyword(NamespacedKeyword::new("test", "attribute")), Span(22, 37))));
|
|
||||||
|
|
||||||
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 input = input.with_spans();
|
|
||||||
let stream = input.atom_stream();
|
|
||||||
let result = Tx::entity().parse(stream).map(|x| x.0);
|
|
||||||
|
|
||||||
assert_eq!(result,
|
|
||||||
Ok(Entity::MapNotation(expected)));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,106 +0,0 @@
|
||||||
// Copyright 2016 Mozilla
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
||||||
// this file except in compliance with the License. You may obtain a copy of the
|
|
||||||
// License at http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
// Unless required by applicable law or agreed to in writing, software distributed
|
|
||||||
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
|
|
||||||
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
|
|
||||||
// specific language governing permissions and limitations under the License.
|
|
||||||
|
|
||||||
extern crate edn;
|
|
||||||
extern crate combine;
|
|
||||||
extern crate mentat_tx;
|
|
||||||
extern crate mentat_tx_parser;
|
|
||||||
|
|
||||||
use edn::parse;
|
|
||||||
use edn::symbols::NamespacedKeyword;
|
|
||||||
use mentat_tx::entities::{
|
|
||||||
AtomOrLookupRefOrVectorOrMapNotation,
|
|
||||||
Entid,
|
|
||||||
EntidOrLookupRefOrTempId,
|
|
||||||
Entity,
|
|
||||||
OpType,
|
|
||||||
TempId,
|
|
||||||
};
|
|
||||||
use mentat_tx_parser::Tx;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_float_and_uuid() {
|
|
||||||
let expected_uuid = edn::Uuid::parse_str("267bab92-ee39-4ca2-b7f0-1163a85af1fb").expect("valid uuid");
|
|
||||||
let input = r#"
|
|
||||||
[[:db/add 101 :test/a #uuid "267bab92-ee39-4ca2-b7f0-1163a85af1fb"]
|
|
||||||
[:db/add 102 :test/b #f NaN]]
|
|
||||||
"#;
|
|
||||||
let edn = parse::value(input).expect("to parse test input");
|
|
||||||
|
|
||||||
let result = Tx::parse(&edn);
|
|
||||||
assert_eq!(result.unwrap(),
|
|
||||||
vec![
|
|
||||||
Entity::AddOrRetract {
|
|
||||||
op: OpType::Add,
|
|
||||||
e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(101)),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(edn::ValueAndSpan::new(edn::SpannedValue::Uuid(expected_uuid), edn::Span(23, 67))),
|
|
||||||
},
|
|
||||||
Entity::AddOrRetract {
|
|
||||||
op: OpType::Add,
|
|
||||||
e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(102)),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "b")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(edn::ValueAndSpan::new(edn::SpannedValue::Float(edn::OrderedFloat(std::f64::NAN)), edn::Span(91, 97))),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_entities() {
|
|
||||||
let input = r#"
|
|
||||||
[[:db/add 101 :test/a "v"]
|
|
||||||
[:db/add "tempid" :test/a "v"]
|
|
||||||
[:db/retract 102 :test/b "w"]]"#;
|
|
||||||
|
|
||||||
let edn = parse::value(input).expect("to parse test input");
|
|
||||||
|
|
||||||
let result = Tx::parse(&edn);
|
|
||||||
assert_eq!(result.unwrap(),
|
|
||||||
vec![
|
|
||||||
Entity::AddOrRetract {
|
|
||||||
op: OpType::Add,
|
|
||||||
e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(101)),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(edn::ValueAndSpan::new(edn::SpannedValue::Text("v".into()), edn::Span(23, 26))),
|
|
||||||
},
|
|
||||||
Entity::AddOrRetract {
|
|
||||||
op: OpType::Add,
|
|
||||||
e: EntidOrLookupRefOrTempId::TempId(TempId::External("tempid".into())),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "a")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(edn::ValueAndSpan::new(edn::SpannedValue::Text("v".into()), edn::Span(55, 58))),
|
|
||||||
},
|
|
||||||
Entity::AddOrRetract {
|
|
||||||
op: OpType::Retract,
|
|
||||||
e: EntidOrLookupRefOrTempId::Entid(Entid::Entid(102)),
|
|
||||||
a: Entid::Ident(NamespacedKeyword::new("test", "b")),
|
|
||||||
v: AtomOrLookupRefOrVectorOrMapNotation::Atom(edn::ValueAndSpan::new(edn::SpannedValue::Text("w".into()), edn::Span(86, 89))),
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn test_reverse_notation_illegal_nested_values() {
|
|
||||||
// Verify that we refuse to parse direct reverse notation with nested value maps or vectors.
|
|
||||||
|
|
||||||
let input = "[[:db/add 100 :test/_dangling {:test/many 13}]]";
|
|
||||||
let edn = parse::value(input).expect("to parse test input");
|
|
||||||
let result = Tx::parse(&edn);
|
|
||||||
// TODO: it would be much better to assert details about the error (here and below), but right
|
|
||||||
// now the error message isn't clear that the given value isn't valid for the backward attribute
|
|
||||||
// :test/_dangling.
|
|
||||||
assert!(result.is_err());
|
|
||||||
|
|
||||||
let input = "[[:db/add 100 :test/_dangling [:test/many 13]]]";
|
|
||||||
let edn = parse::value(input).expect("to parse test input");
|
|
||||||
let result = Tx::parse(&edn);
|
|
||||||
assert!(result.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: test error handling in select cases.
|
|
Loading…
Reference in a new issue