pub struct CollectionWithId<T> { /* private fields */ }
Expand description

A Collection with identifier support.

Implementations§

source§

impl<T: Id<T>> CollectionWithId<T>

source

pub fn new(v: Vec<T>) -> Result<Self, Error<T>>

Creates a CollectionWithId from a Vec. Fails if there is duplicates in identifiers.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
assert_eq!(2, c.len());
assert_eq!(Some(&Obj("foo")), c.get("foo"));
assert!(CollectionWithId::new(vec![Obj("foo"), Obj("foo")]).is_err());
source

pub fn get_id_to_idx(&self) -> &HashMap<String, Idx<T>>

Get a reference to the String to Idx<T> internal mapping.

Examples
use typed_index_collection::{CollectionWithId, Id};
use std::collections::HashMap;

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
assert_eq!(2, c.len());
assert_eq!(2, c.get_id_to_idx().len());
source

pub fn indexes(&self) -> impl Iterator<Item = Idx<T>>

Iterate over the list of indexes of the CollectionWithId.

use typed_index_collection::{CollectionWithId, Id};
use std::collections::HashMap;

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let mut indexes = c.indexes();
let next_index = indexes.next().unwrap();
assert_eq!("foo", c[next_index].id());
let next_index = indexes.next().unwrap();
assert_eq!("bar", c[next_index].id());
assert_eq!(None, indexes.next());
source

pub fn index_mut(&mut self, idx: Idx<T>) -> RefMut<'_, T>

Access to a mutable reference of the corresponding object.

The drop of the proxy object panic if the identifier is modified to an identifier already on the collection.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let idx = c.get_idx("foo").unwrap();
c.index_mut(idx).0 = "baz";
assert!(!c.contains_id("foo"));
assert_eq!(Some(&Obj("baz")), c.get("baz"));
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let idx = c.get_idx("foo").unwrap();
c.index_mut(idx).0 = "bar"; // panic
source

pub fn get_mut(&mut self, id: &str) -> Option<RefMut<'_, T>>

Returns an option of a mutable reference of the corresponding object.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
c.get_mut("foo").unwrap().0 = "baz";
assert!(!c.contains_id("foo"));
assert_eq!(Some(&Obj("baz")), c.get("baz"));
source

pub fn push(&mut self, item: T) -> Result<Idx<T>, Error<T>>

Push an element in the CollectionWithId. Fails if the identifier of the new object is already in the collection.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let baz_idx = c.push(Obj("baz")).unwrap();
assert_eq!(&Obj("baz"), &c[baz_idx]);
assert!(c.push(Obj("baz")).is_err());

let foobar_idx = c.push(Obj("foobar")).unwrap();
assert_eq!(&Obj("baz"), &c[baz_idx]);
assert_eq!(&Obj("foobar"), &c[foobar_idx]);
source

pub fn retain<F: FnMut(&T) -> bool>(&mut self, f: F)

Retains the elements matching predicate parameter from the current CollectionWithId object

Examples
use typed_index_collection::{CollectionWithId, Id};
use std::collections::HashSet;

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c = CollectionWithId::new(vec![Obj("foo"), Obj("bar"), Obj("qux")]).unwrap();
let mut ids_to_keep: HashSet<String> = HashSet::new();
ids_to_keep.insert("foo".to_string());
ids_to_keep.insert("qux".to_string());
c.retain(|item| ids_to_keep.contains(item.id()));
assert_eq!(2, c.len());
assert_eq!(Some(&Obj("foo")), c.get("foo"));
assert_eq!(Some(&Obj("qux")), c.get("qux"));
source

pub fn try_merge(&mut self, other: Self) -> Result<(), Error<T>>

Merge a CollectionWithId parameter into the current one. Fails if any identifier into the CollectionWithId parameter is already in the collection.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c1 = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let mut c2 = CollectionWithId::new(vec![Obj("foo"), Obj("qux")]).unwrap();
let mut c3 = CollectionWithId::new(vec![Obj("corge"), Obj("grault")]).unwrap();
assert!(c1.try_merge(c2).is_err());

c1.try_merge(c3);
assert_eq!(4, c1.len());
source

pub fn merge(&mut self, other: Self)

Merge a CollectionWithId parameter into the current one. If any identifier into the CollectionWithId parameter is already in the collection, CollectionWithId is not added.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c1 = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let mut c2 = CollectionWithId::new(vec![Obj("foo"), Obj("qux")]).unwrap();
c1.merge(c2);
assert_eq!(3, c1.len());
source

pub fn merge_with<I, F>(&mut self, iterator: I, f: F)where F: FnMut(&mut T, &T), I: IntoIterator<Item = T>,

Merge all elements of an Iterator into the current CollectionWithId. If any identifier of an inserted element is already in the collection, the closure is called, with first parameter being the element with this identifier already in the collection, and the second parameter is the element to be inserted.

use typed_index_collection::{CollectionWithId, Id};

#[derive(Debug, Default)]
struct ObjectId {
   id: &'static str,
   name: &'static str,
}

impl Id<ObjectId> for ObjectId {
   fn id(&self) -> &str {
       self.id
   }
   fn set_id(&mut self, _id: String) {
       unimplemented!()
   }
}

let mut collection = CollectionWithId::default();
let _ = collection.push(ObjectId {
    id: "foo",
    name: "Bob",
});
let vec = vec![ObjectId {
    id: "bar",
    name: "SpongeBob SquarePants",
}];
// Merge without collision of identifiers
collection.merge_with(vec, |_, _| {
  // Should never come here
  assert!(false);
});
assert!(collection.get("bar").is_some());

let vec = vec![ObjectId {
    id: "foo",
    name: "Bob Marley",
}];
// Merge with collision of identifiers
collection.merge_with(vec, |source, to_merge| {
    source.name = to_merge.name;
});
let foo = collection.get("foo").unwrap();
assert_eq!("Bob Marley", foo.name);
source

pub fn is_empty(&self) -> bool

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c: CollectionWithId<Obj> = CollectionWithId::default();
assert!(c.is_empty());
source§

impl<T: Id<T> + WithId> CollectionWithId<T>

source

pub fn get_or_create<'a>(&'a mut self, id: &str) -> RefMut<'a, T>

Get a mutable reference of the corresponding object or create it

Examples

#[derive(PartialEq, Debug)]
struct Obj(String);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { &self.0 }
    fn set_id(&mut self, id: String) { self.0 = id; }
}

impl WithId for Obj {
    fn with_id(id: &str) -> Self {
        let mut r = Obj("id".into());
        r.0 = id.to_owned();
        r
    }
}

let mut c = CollectionWithId::from(Obj("1".into()));
let obj = c.get_or_create("2");
assert_eq!("2", obj.0);
source§

impl<T: Id<T>> CollectionWithId<T>

source

pub fn get_or_create_with<'a, F>(&'a mut self, id: &str, f: F) -> RefMut<'a, T>where F: FnMut() -> T,

Get a mutable reference of the corresponding object or create it and apply a function on it.

Examples
use typed_index_collection::{CollectionWithId, Id, WithId};

#[derive(PartialEq, Debug)]
struct Obj(String, String);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { &self.0 }
    fn set_id(&mut self, id: String) { self.0 = id; }
}

impl WithId for Obj {
    fn with_id(id: &str) -> Self {
        let mut r = Obj("id".into(), "name".into());
        r.0 = id.to_owned();
        r
    }
}

let mut c = CollectionWithId::from(Obj("1".into(), "foo".into()));
let obj = c.get_or_create_with("2", || Obj("bob".into(), "bar".into()));
assert_eq!("2", obj.0);
assert_eq!("bar", obj.1);
source§

impl<T> CollectionWithId<T>

source

pub fn contains_id(&self, id: &str) -> bool

Returns true if the collection contains a value for the specified id.

use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
assert!(c.contains_id("foo"));
assert!(!c.contains_id("baz"));
source

pub fn get_idx(&self, id: &str) -> Option<Idx<T>>

Returns the index corresponding to the identifier.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let idx = c.get_idx("foo").unwrap();
assert_eq!(&Obj("foo"), &c[idx]);
assert!(c.get_idx("baz").is_none());
source

pub fn get(&self, id: &str) -> Option<&T>

Returns a reference to the object corresponding to the identifier.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
assert_eq!(Some(&Obj("foo")), c.get("foo"));
assert!(!c.contains_id("baz"));
source

pub fn into_vec(self) -> Vec<T>

Converts self into a vector without clones or allocation.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let v = c.into_vec();
assert_eq!(vec![Obj("foo"), Obj("bar")], v);
source

pub fn take(&mut self) -> Vec<T>

Takes the corresponding vector without clones or allocation, leaving self empty.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let v = c.take();
assert_eq!(vec![Obj("foo"), Obj("bar")], v);
assert_eq!(0, c.len());

Methods from Deref<Target = Collection<T>>§

source

pub fn len(&self) -> usize

Returns the number of elements in the collection, also referred to as its ‘length’.

Examples
use typed_index_collection::Collection;

let c: Collection<i32> = Collection::new(vec![1, 1, 2, 3, 5, 8]);
assert_eq!(6, c.len());
source

pub fn iter(&self) -> Iter<'_, T>

Iterates over the (Idx<T>, &T) of the Collection.

Examples
use typed_index_collection::{Collection, Idx};

let c: Collection<i32> = Collection::new(vec![1, 1, 2, 3, 5, 8]);
let (k, v): (Idx<i32>, &i32) = c.iter().nth(4).unwrap();
assert_eq!(&5, v);
assert_eq!(&5, &c[k]);
source

pub fn values(&self) -> Iter<'_, T>

Iterates over the &T of the Collection.

Examples
use typed_index_collection::Collection;

let c: Collection<i32> = Collection::new(vec![1, 1, 2, 3, 5, 8]);
let values: Vec<&i32> = c.values().collect();
assert_eq!(vec![&1, &1, &2, &3, &5, &8], values);
source

pub fn iter_from<I>(&self, indexes: I) -> impl Iterator<Item = &T>where I: IntoIterator, I::Item: Borrow<Idx<T>>,

Iterates on the objects corresponding to the given indices.

Examples
use typed_index_collection::{Collection, Idx};
use std::collections::BTreeSet;

let c = Collection::new(vec!["bike", "bus", "walking", "car", "metro", "train"]);
let transit_indices: BTreeSet<Idx<&str>> = get_transit_indices(&c);
let transit_refs: Vec<&&str> = c.iter_from(&transit_indices).collect();
assert_eq!(vec![&"bus", &"metro", &"train"], transit_refs);
source

pub fn is_empty(&self) -> bool

Examples
use typed_index_collection::Collection;

#[derive(PartialEq, Debug)]
struct Obj;

let mut c: Collection<Obj> = Collection::default();
assert!(c.is_empty());

Trait Implementations§

source§

impl<T: Clone> Clone for CollectionWithId<T>

source§

fn clone(&self) -> CollectionWithId<T>

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> Debug for CollectionWithId<T>

source§

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

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

impl<T> Default for CollectionWithId<T>

source§

fn default() -> Self

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

impl<T> Deref for CollectionWithId<T>

§

type Target = Collection<T>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Collection<T>

Dereferences the value.
source§

impl<'de, T> Deserialize<'de> for CollectionWithId<T>where T: Deserialize<'de> + Id<T>,

source§

fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<T: Id<T>> Extend<T> for CollectionWithId<T>

source§

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

Extend a CollectionWithId with the content of an iterator of CollectionWithId without duplicated ids.

Examples
use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let mut c1 = CollectionWithId::new(vec![Obj("foo"), Obj("bar")]).unwrap();
let mut c2 = CollectionWithId::new(vec![Obj("foo"), Obj("qux")]).unwrap();
c1.extend(c2);
assert_eq!(3, c1.len());
testing_logger::validate(|captured_logs| {
  assert!(captured_logs[0].level == tracing::log::Level::Warn);
  assert!(captured_logs[0].body.contains("identifier foo already exists"));
});
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<T: Id<T>> From<T> for CollectionWithId<T>

Creates a CollectionWithId from one element.

Examples

use typed_index_collection::{CollectionWithId, Id};

#[derive(PartialEq, Debug)]
struct Obj(&'static str);

impl Id<Obj> for Obj {
    fn id(&self) -> &str { self.0 }
    fn set_id(&mut self, id: String) { unimplemented!(); }
}

let collection: CollectionWithId<Obj> = CollectionWithId::from(Obj("some_id"));
assert_eq!(1, collection.len());
let obj = collection.into_iter().next().unwrap();
assert_eq!("some_id", obj.id());
source§

fn from(object: T) -> Self

Converts to this type from the input type.
source§

impl<'a, T> IntoIterator for &'a CollectionWithId<T>

§

type Item = (Idx<T>, &'a T)

The type of the elements being iterated over.
§

type IntoIter = Map<Enumerate<Iter<'a, T>>, fn(_: (usize, &T)) -> (Idx<T>, &T)>

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<T> IntoIterator for CollectionWithId<T>

§

type Item = T

The type of the elements being iterated over.
§

type IntoIter = IntoIter<T, Global>

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<T: PartialEq> PartialEq<CollectionWithId<T>> for CollectionWithId<T>

source§

fn eq(&self, other: &CollectionWithId<T>) -> 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<T> Serialize for CollectionWithId<T>where T: Serialize + Id<T>,

source§

fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>where S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<T> RefUnwindSafe for CollectionWithId<T>where T: RefUnwindSafe,

§

impl<T> Send for CollectionWithId<T>where T: Send,

§

impl<T> Sync for CollectionWithId<T>where T: Sync,

§

impl<T> Unpin for CollectionWithId<T>where T: Unpin,

§

impl<T> UnwindSafe for CollectionWithId<T>where 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> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<T> DeserializeOwned for Twhere T: for<'de> Deserialize<'de>,