Part 3: Implement Deref and DerefMut for InternSet.

This pattern is generally how newtype wrappers (like `struct
Foo(Bar)`) are implemented in Rust.
This commit is contained in:
Nick Alexander 2018-07-02 10:12:13 -07:00
parent 02a163a10f
commit 106d6fae11
2 changed files with 23 additions and 9 deletions

View file

@ -619,7 +619,7 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher {
let (terms_with_temp_ids_and_lookup_refs, tempid_set, lookup_ref_set) = self.entities_into_terms_with_temp_ids_and_lookup_refs(entities)?; let (terms_with_temp_ids_and_lookup_refs, tempid_set, lookup_ref_set) = self.entities_into_terms_with_temp_ids_and_lookup_refs(entities)?;
// Pipeline stage 2: resolve lookup refs -> terms with tempids. // Pipeline stage 2: resolve lookup refs -> terms with tempids.
let lookup_ref_avs: Vec<&(i64, TypedValue)> = lookup_ref_set.inner.iter().map(|rc| &**rc).collect(); let lookup_ref_avs: Vec<&(i64, TypedValue)> = lookup_ref_set.iter().map(|rc| &**rc).collect();
let lookup_ref_map: AVMap = self.store.resolve_avs(&lookup_ref_avs[..])?; let lookup_ref_map: AVMap = self.store.resolve_avs(&lookup_ref_avs[..])?;
let terms_with_temp_ids = self.resolve_lookup_refs(&lookup_ref_map, terms_with_temp_ids_and_lookup_refs)?; let terms_with_temp_ids = self.resolve_lookup_refs(&lookup_ref_map, terms_with_temp_ids_and_lookup_refs)?;
@ -700,8 +700,8 @@ impl<'conn, 'a, W> Tx<'conn, 'a, W> where W: TransactWatcher {
} }
// Verify that every tempid we interned either resolved or has been allocated. // Verify that every tempid we interned either resolved or has been allocated.
assert_eq!(tempids.len(), tempid_set.inner.len()); assert_eq!(tempids.len(), tempid_set.len());
for tempid in &tempid_set.inner { for tempid in tempid_set.iter() {
assert!(tempids.contains_key(&**tempid)); assert!(tempids.contains_key(&**tempid));
} }

View file

@ -12,6 +12,10 @@
use std::collections::HashSet; use std::collections::HashSet;
use std::hash::Hash; use std::hash::Hash;
use std::ops::{
Deref,
DerefMut,
};
use ::{ use ::{
ValueRc, ValueRc,
@ -26,7 +30,21 @@ use ::{
/// See https://en.wikipedia.org/wiki/String_interning for discussion. /// See https://en.wikipedia.org/wiki/String_interning for discussion.
#[derive(Clone, Debug, Default, Eq, PartialEq)] #[derive(Clone, Debug, Default, Eq, PartialEq)]
pub struct InternSet<T> where T: Eq + Hash { pub struct InternSet<T> where T: Eq + Hash {
pub inner: HashSet<ValueRc<T>>, inner: HashSet<ValueRc<T>>,
}
impl<T> Deref for InternSet<T> where T: Eq + Hash {
type Target = HashSet<ValueRc<T>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<T> DerefMut for InternSet<T> where T: Eq + Hash {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
} }
impl<T> InternSet<T> where T: Eq + Hash { impl<T> InternSet<T> where T: Eq + Hash {
@ -36,10 +54,6 @@ impl<T> InternSet<T> where T: Eq + Hash {
} }
} }
pub fn len(&self) -> usize {
self.inner.len()
}
/// Intern a value, providing a ref-counted handle to the interned value. /// Intern a value, providing a ref-counted handle to the interned value.
/// ///
/// ``` /// ```
@ -56,7 +70,7 @@ impl<T> InternSet<T> where T: Eq + Hash {
/// ///
/// let out_two = s.intern(two); /// let out_two = s.intern(two);
/// assert_eq!(out_one, out_two); /// assert_eq!(out_one, out_two);
/// assert_eq!(1, s.inner.len()); /// assert_eq!(1, s.len());
/// // assert!(&out_one.ptr_eq(&out_two)); // Nightly-only. /// // assert!(&out_one.ptr_eq(&out_two)); // Nightly-only.
/// ``` /// ```
pub fn intern<R: Into<ValueRc<T>>>(&mut self, value: R) -> ValueRc<T> { pub fn intern<R: Into<ValueRc<T>>>(&mut self, value: R) -> ValueRc<T> {