Struct atom_table::AtomTable

source ·
pub struct AtomTable<T, I>where
    I: From<usize>,{ /* private fields */ }
Expand description

A data structure that lets you use strongly typed indices/IDs instead of bulky values, performing a lookup in both directions.

T is your value type, and I is your index/ID type.

Typically I should be a “newtype” (tuple struct) wrapping usize and with Copy and From<usize> implemented for it and From<I> implemented for usize. The derive_more crate may be useful for implementing these traits.

Right now, the values must have an implementation of Clone. This may be loosened in the future if there is a straightforward and compelling way and reason to do so.

Values cannot be modified once inserted, because remaining the same is essential to providing the invariant (and, each value is stored twice within the structure at this time)

Implementations§

source§

impl<V, I> AtomTable<V, I>where I: From<usize>,

source

pub fn new() -> Selfwhere I: Copy,

Make a new (empty) table.

source

pub fn iter(&self) -> impl Iterator<Item = &V>

Iterate over the values.

source

pub fn iter_enumerated(&self) -> impl Iterator<Item = (I, &V)>

Iterate over the (ID, value) pairs.

source

pub fn get(&self, id: I) -> Option<&V>where usize: From<I>,

Look up the ID and return the corresponding value, if any.

source

pub fn get_or_create_id_for_owned_value(&mut self, value: V) -> Iwhere V: Clone + Hash + Eq, I: Copy,

Look up the provided, owned value, and either return the existing ID for it, or add it to the table and return the newly created ID for it.

  • See AtomTable::get_id if you want to only get the ID if one already exists.
  • See AtomTable::get_or_create_id if you do not already own the value or are unwilling to transfer ownership - it will do an extra clone for you, as late as possible, if necessary.
Panics

Panics (assert) if an internal invariant is violated, which should not be possible.

source

pub fn get_or_create_id<Q>(&mut self, value: &Q) -> Iwhere I: Copy, V: Clone + Hash + Eq + Borrow<Q>, Q: ?Sized + Hash + Eq + ToOwned<Owned = V>,

Look up the provided value, and either return the existing ID for it, or add it to the table and return the newly created ID for it.

The generic type usage here is to allow usage of things that can be turned into owned values (generally by cloning), and which may be used without cloning to find an existing ID.

Panics

Panics (assert) if an internal invariant is violated, which should not be possible.

source

pub fn get_id<Q>(&self, value: &Q) -> Option<I>where I: Copy, V: Hash + Eq + Borrow<Q>, Q: Hash + Eq + ?Sized,

Look up the provided value and return the existing ID for it, if any.

The generic type usage here mirrors that used in HashMap<K, V>::get, to allow e.g. &str to be passed here if the value type is String.

source§

impl<V, I> AtomTable<V, I>where I: From<usize>,

source

pub fn try_transform<U: Hash + Eq + Clone>( &self, f: impl FnMut(&V) -> U ) -> Result<AtomTable<U, I>, NonUniqueTransformOutputError>where I: Eq + Debug,

Apply a function to all values to produce a new atom table with correspondence between the IDs.

Your function f must return unique outputs when given the unique inputs, so the returned AtomTable may still support ID lookup from a value (data structure invariant).

Requires (default) feature “transform”

Errors

Returns an NonUniqueTransformOutputError error if your function does not return unique outputs for each input.

source

pub fn try_transform_res<U: Hash + Eq + Clone, E>( &self, f: impl FnMut(&V) -> Result<U, E> ) -> Result<AtomTable<U, I>, TransformResError<E>>where I: Eq + Debug,

Apply a function returning Result<T, E> to all values to produce a new atom table with correspondence between the IDs. (That is, new_table.get(id) on the new table will return effectively old_table.get(id).map(p).ok().flatten())

Requires (default) feature “transform”

Errors

Returns an error if your transform function returns an error at any point.

Your error type will be wrapped by TransformResError so that NonUniqueTransformOutputError may also be returned, if your function does not return unique outputs for each input, which would break the invariant of the data structure.

Panics

Panics if an internal invariant is somehow violated, which should not be possible.

Trait Implementations§

source§

impl<T: Clone, I> Clone for AtomTable<T, I>where I: From<usize> + Clone,

source§

fn clone(&self) -> AtomTable<T, I>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<T: Debug, I> Debug for AtomTable<T, I>where I: From<usize> + Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<T, I> Default for AtomTable<T, I>where I: From<usize> + Copy,

source§

fn default() -> Self

Returns the “default value” for a type. Read more
source§

impl<V, I> Extend<V> for AtomTable<V, I>where V: Hash + Eq + Clone, I: From<usize> + Copy,

Allow extending from an iterator over values: duplicate values are silently ignored/discarded.

source§

fn extend<T: IntoIterator<Item = V>>(&mut self, iter: T)

Extends a collection with the contents of an iterator. Read more
source§

fn extend_one(&mut self, item: A)

🔬This is a nightly-only experimental API. (extend_one)
Extends a collection with exactly one element.
source§

fn extend_reserve(&mut self, additional: usize)

🔬This is a nightly-only experimental API. (extend_one)
Reserves capacity in a collection for the given number of additional elements. Read more
source§

impl<V, I> From<AtomTable<V, I>> for Vec<V>where I: From<usize>,

Conversion to a normal Vec

source§

fn from(value: AtomTable<V, I>) -> Self

Converts to this type from the input type.
source§

impl<V, I> FromIterator<V> for AtomTable<V, I>where I: From<usize>, V: Clone + Hash + Eq,

Allow creation from an iterator over values: duplicate values are silently ignored/discarded.

This is what allows us to use Iterator::collect into an AtomTable.

source§

fn from_iter<T: IntoIterator<Item = V>>(iter: T) -> Self

Creates a value from an iterator. Read more
source§

impl<V, I> IntoIterator for AtomTable<V, I>where I: From<usize>,

Provide into_iter() which iterates only over the values.

§

type Item = V

The type of the elements being iterated over.
§

type IntoIter = <TiVec<I, V> as IntoIterator>::IntoIter

Which kind of iterator are we turning this into?
source§

fn into_iter(self) -> Self::IntoIter

Creates an iterator from a value. Read more
source§

impl<V, I> PartialEq<AtomTable<V, I>> for AtomTable<V, I>where I: From<usize>, V: PartialEq,

Equality comparison provided only when associated value type supports equality.

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<V, I> Eq for AtomTable<V, I>where I: From<usize>, V: Eq,

Auto Trait Implementations§

§

impl<T, I> RefUnwindSafe for AtomTable<T, I>where I: RefUnwindSafe, T: RefUnwindSafe,

§

impl<T, I> Send for AtomTable<T, I>where I: Send, T: Send,

§

impl<T, I> Sync for AtomTable<T, I>where I: Sync, T: Sync,

§

impl<T, I> Unpin for AtomTable<T, I>where I: Unpin, T: Unpin,

§

impl<T, I> UnwindSafe for AtomTable<T, I>where I: UnwindSafe, T: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for Twhere T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere T: ?Sized,

const: unstable · source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

const: unstable · source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for Twhere U: From<T>,

const: unstable · source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for Twhere T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for Twhere U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
const: unstable · source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for Twhere U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
const: unstable · source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.