Part 7: Improve TermBuilder
interface; expose lookup refs and tx functions.
These are functions on `TermBuilder` itself to prevent mixing mutable and immutable references in the most natural style. That is, ``` builder.add(e, a, builder.lookup_ref(...)) ``` fails because `add` borrows `builder` mutably and `lookup_ref` borrows `builder` immutably. There's nothing here that requires a specific builder (since we're not interning lookup refs on the builder, like we are tempids) so we don't need an instance.
This commit is contained in:
parent
06056a8468
commit
eb1df31ac4
1 changed files with 23 additions and 10 deletions
|
@ -54,14 +54,17 @@
|
||||||
|
|
||||||
use edn::{
|
use edn::{
|
||||||
InternSet,
|
InternSet,
|
||||||
|
PlainSymbol,
|
||||||
ValueRc,
|
ValueRc,
|
||||||
};
|
};
|
||||||
use edn::entities::{
|
use edn::entities::{
|
||||||
AttributePlace,
|
AttributePlace,
|
||||||
Entity,
|
Entity,
|
||||||
EntityPlace,
|
EntityPlace,
|
||||||
|
LookupRef,
|
||||||
OpType,
|
OpType,
|
||||||
TempId,
|
TempId,
|
||||||
|
TxFunction,
|
||||||
ValuePlace,
|
ValuePlace,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -91,7 +94,7 @@ pub struct EntityBuilder<T: BuildTerms + Sized> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait BuildTerms where Self: Sized {
|
pub trait BuildTerms where Self: Sized {
|
||||||
fn named_tempid(&mut self, name: String) -> ValueRc<TempId>;
|
fn named_tempid<I>(&mut self, name: I) -> ValueRc<TempId> where I: Into<String>;
|
||||||
fn describe_tempid(self, name: &str) -> EntityBuilder<Self>;
|
fn describe_tempid(self, name: &str) -> EntityBuilder<Self>;
|
||||||
fn describe<E>(self, entity: E) -> EntityBuilder<Self> where E: Into<EntityPlace<TypedValue>>;
|
fn describe<E>(self, entity: E) -> EntityBuilder<Self> where E: Into<EntityPlace<TypedValue>>;
|
||||||
fn add<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
fn add<E, A, V>(&mut self, e: E, a: A, v: V) -> Result<()>
|
||||||
|
@ -105,12 +108,12 @@ pub trait BuildTerms where Self: Sized {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BuildTerms for TermBuilder {
|
impl BuildTerms for TermBuilder {
|
||||||
fn named_tempid(&mut self, name: String) -> ValueRc<TempId> {
|
fn named_tempid<I>(&mut self, name: I) -> ValueRc<TempId> where I: Into<String> {
|
||||||
self.tempids.intern(TempId::External(name))
|
self.tempids.intern(TempId::External(name.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn describe_tempid(mut self, name: &str) -> EntityBuilder<Self> {
|
fn describe_tempid(mut self, name: &str) -> EntityBuilder<Self> {
|
||||||
let e = self.named_tempid(name.into());
|
let e = self.named_tempid(name);
|
||||||
self.describe(e)
|
self.describe(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -158,6 +161,16 @@ impl TermBuilder {
|
||||||
pub fn numbered_tempid(&mut self, id: i64) -> ValueRc<TempId> {
|
pub fn numbered_tempid(&mut self, id: i64) -> ValueRc<TempId> {
|
||||||
self.tempids.intern(TempId::Internal(id))
|
self.tempids.intern(TempId::Internal(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn lookup_ref<A, V>(a: A, v: V) -> LookupRef<TypedValue>
|
||||||
|
where A: Into<AttributePlace>,
|
||||||
|
V: Into<TypedValue> {
|
||||||
|
LookupRef { a: a.into(), v: v.into() }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tx_function(op: &str) -> TxFunction {
|
||||||
|
TxFunction { op: PlainSymbol::plain(op) }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> EntityBuilder<T> where T: BuildTerms {
|
impl<T> EntityBuilder<T> where T: BuildTerms {
|
||||||
|
@ -217,12 +230,12 @@ impl<'a, 'c> InProgressBuilder<'a, 'c> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'c> BuildTerms for InProgressBuilder<'a, 'c> {
|
impl<'a, 'c> BuildTerms for InProgressBuilder<'a, 'c> {
|
||||||
fn named_tempid(&mut self, name: String) -> ValueRc<TempId> {
|
fn named_tempid<I>(&mut self, name: I) -> ValueRc<TempId> where I: Into<String> {
|
||||||
self.builder.named_tempid(name)
|
self.builder.named_tempid(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn describe_tempid(mut self, name: &str) -> EntityBuilder<InProgressBuilder<'a, 'c>> {
|
fn describe_tempid(mut self, name: &str) -> EntityBuilder<InProgressBuilder<'a, 'c>> {
|
||||||
let e = self.builder.named_tempid(name.into());
|
let e = self.builder.named_tempid(name.to_string());
|
||||||
self.describe(e)
|
self.describe(e)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,7 +301,7 @@ mod testing {
|
||||||
#[test]
|
#[test]
|
||||||
fn test_entity_builder_bogus_entids() {
|
fn test_entity_builder_bogus_entids() {
|
||||||
let mut builder = TermBuilder::new();
|
let mut builder = TermBuilder::new();
|
||||||
let e = builder.named_tempid("x".into());
|
let e = builder.named_tempid("x");
|
||||||
let a1 = fake_known_entid(37); // :db/doc
|
let a1 = fake_known_entid(37); // :db/doc
|
||||||
let a2 = fake_known_entid(999);
|
let a2 = fake_known_entid(999);
|
||||||
let v = TypedValue::typed_string("Some attribute");
|
let v = TypedValue::typed_string("Some attribute");
|
||||||
|
@ -340,7 +353,7 @@ mod testing {
|
||||||
let a_many = in_progress.get_entid(&kw!(:foo/many)).expect(":foo/many");
|
let a_many = in_progress.get_entid(&kw!(:foo/many)).expect(":foo/many");
|
||||||
|
|
||||||
let mut builder = in_progress.builder();
|
let mut builder = in_progress.builder();
|
||||||
let e_x = builder.named_tempid("x".into());
|
let e_x = builder.named_tempid("x");
|
||||||
let v_many_1 = TypedValue::typed_string("Some text");
|
let v_many_1 = TypedValue::typed_string("Some text");
|
||||||
let v_many_2 = TypedValue::typed_string("Other text");
|
let v_many_2 = TypedValue::typed_string("Other text");
|
||||||
builder.add(e_x.clone(), kw!(:foo/many), v_many_1).expect("add succeeded");
|
builder.add(e_x.clone(), kw!(:foo/many), v_many_1).expect("add succeeded");
|
||||||
|
@ -378,8 +391,8 @@ mod testing {
|
||||||
// Scoped borrow of in_progress.
|
// Scoped borrow of in_progress.
|
||||||
{
|
{
|
||||||
let mut builder = TermBuilder::new();
|
let mut builder = TermBuilder::new();
|
||||||
let e_x = builder.named_tempid("x".into());
|
let e_x = builder.named_tempid("x");
|
||||||
let e_y = builder.named_tempid("y".into());
|
let e_y = builder.named_tempid("y");
|
||||||
let a_ref = in_progress.get_entid(&foo_ref).expect(":foo/ref");
|
let a_ref = in_progress.get_entid(&foo_ref).expect(":foo/ref");
|
||||||
let a_one = in_progress.get_entid(&foo_one).expect(":foo/one");
|
let a_one = in_progress.get_entid(&foo_one).expect(":foo/one");
|
||||||
let a_many = in_progress.get_entid(&foo_many).expect(":foo/many");
|
let a_many = in_progress.get_entid(&foo_many).expect(":foo/many");
|
||||||
|
|
Loading…
Reference in a new issue