Struct typed_index_collection::CollectionWithId
source · pub struct CollectionWithId<T> { /* private fields */ }
Expand description
A Collection
with identifier support.
Implementations§
source§impl<T: Id<T>> CollectionWithId<T>
impl<T: Id<T>> CollectionWithId<T>
sourcepub fn new(v: Vec<T>) -> Result<Self, Error<T>>
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());
sourcepub fn get_id_to_idx(&self) -> &HashMap<String, Idx<T>>
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());
sourcepub fn indexes(&self) -> impl Iterator<Item = Idx<T>>
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());
sourcepub fn index_mut(&mut self, idx: Idx<T>) -> RefMut<'_, T>
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
sourcepub fn get_mut(&mut self, id: &str) -> Option<RefMut<'_, T>>
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"));
sourcepub fn push(&mut self, item: T) -> Result<Idx<T>, Error<T>>
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]);
sourcepub fn retain<F: FnMut(&T) -> bool>(&mut self, f: F)
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"));
sourcepub fn try_merge(&mut self, other: Self) -> Result<(), Error<T>>
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());
sourcepub fn merge(&mut self, other: Self)
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());
sourcepub fn merge_with<I, F>(&mut self, iterator: I, f: F)where
F: FnMut(&mut T, &T),
I: IntoIterator<Item = T>,
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);
sourcepub fn is_empty(&self) -> bool
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>
impl<T: Id<T> + WithId> CollectionWithId<T>
sourcepub fn get_or_create<'a>(&'a mut self, id: &str) -> RefMut<'a, T>
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>
impl<T: Id<T>> CollectionWithId<T>
sourcepub fn get_or_create_with<'a, F>(&'a mut self, id: &str, f: F) -> RefMut<'a, T>where
F: FnMut() -> T,
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>
impl<T> CollectionWithId<T>
sourcepub fn contains_id(&self, id: &str) -> bool
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"));
sourcepub fn get_idx(&self, id: &str) -> Option<Idx<T>>
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());
sourcepub fn get(&self, id: &str) -> Option<&T>
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"));
sourcepub fn into_vec(self) -> Vec<T>
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);
sourcepub fn take(&mut self) -> Vec<T>
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>>§
sourcepub fn len(&self) -> usize
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());
sourcepub fn iter(&self) -> Iter<'_, T>
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]);
sourcepub fn values(&self) -> Iter<'_, T>
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);
sourcepub fn iter_from<I>(&self, indexes: I) -> impl Iterator<Item = &T>where
I: IntoIterator,
I::Item: Borrow<Idx<T>>,
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);
Trait Implementations§
source§impl<T: Clone> Clone for CollectionWithId<T>
impl<T: Clone> Clone for CollectionWithId<T>
source§fn clone(&self) -> CollectionWithId<T>
fn clone(&self) -> CollectionWithId<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<T: Debug> Debug for CollectionWithId<T>
impl<T: Debug> Debug for CollectionWithId<T>
source§impl<T> Default for CollectionWithId<T>
impl<T> Default for CollectionWithId<T>
source§impl<T> Deref for CollectionWithId<T>
impl<T> Deref for CollectionWithId<T>
§type Target = Collection<T>
type Target = Collection<T>
source§fn deref(&self) -> &Collection<T>
fn deref(&self) -> &Collection<T>
source§impl<'de, T> Deserialize<'de> for CollectionWithId<T>where
T: Deserialize<'de> + Id<T>,
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>,
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>where D: Deserializer<'de>,
source§impl<T: Id<T>> Extend<T> for CollectionWithId<T>
impl<T: Id<T>> Extend<T> for CollectionWithId<T>
source§fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
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)
fn extend_one(&mut self, item: A)
extend_one
)source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one
)source§impl<T: Id<T>> From<T> for CollectionWithId<T>
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§impl<'a, T> IntoIterator for &'a CollectionWithId<T>
impl<'a, T> IntoIterator for &'a CollectionWithId<T>
source§impl<T> IntoIterator for CollectionWithId<T>
impl<T> IntoIterator for CollectionWithId<T>
source§impl<T: PartialEq> PartialEq<CollectionWithId<T>> for CollectionWithId<T>
impl<T: PartialEq> PartialEq<CollectionWithId<T>> for CollectionWithId<T>
source§fn eq(&self, other: &CollectionWithId<T>) -> bool
fn eq(&self, other: &CollectionWithId<T>) -> bool
self
and other
values to be equal, and is used
by ==
.