Skip to content

Commit 18afc84

Browse files
committed
Update README and doctests
1 parent 5603263 commit 18afc84

File tree

2 files changed

+182
-16
lines changed

2 files changed

+182
-16
lines changed

README.md

Lines changed: 94 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,37 @@
11
# `identified_vec`
2-
An collection of unique identifiable elements which retains **insertion** order, inspired by [Pointfree's Swift Identified Collections](https://github.com/pointfreeco/swift-identified-collections).
32

4-
Similar to the standard `Vec`, identified vecs maintain their elements in a particular user-specified order. However, unlike `Vec`, `IdentifiedVec` introduce the ability to uniquely identify elements, using a hash table to ensure that no two elements have the same identity, and to efficiently look up elements corresponding to specific identifiers.
3+
[![codecov](https://codecov.io/github/Sajjon/identified_vec/graph/badge.svg?token=Em6TayrP8j)](https://codecov.io/github/Sajjon/identified_vec)
4+
5+
A collection of unique identifiable elements which retains **insertion** order, inspired by [Pointfree's Swift Identified Collections](https://github.com/pointfreeco/swift-identified-collections).
6+
7+
Similar to the standard `Vec`, the `IdentifiedVec` maintain their elements in a particular user-specified order. However, unlike `Vec`, the `IdentifiedVec` introduce the ability to uniquely identify elements, using a hash table to ensure that no two elements have the same identity, and to efficiently look up elements corresponding to specific identifiers.
58

69
`IdentifiedVec` is a useful alternative to `Vec` when you need to be able to efficiently access unique elements by a stable identifier. It is also a useful alternative to `BTreeSet`, where the `Ord` trait requirement may be too strict, an a useful alternative to `HashSet` where `Hash` trait requirement may be too strict.
710

811
You can create an identified vec with any element type that implements the `Identifiable` trait.
912

1013
```rust
14+
extern crate identified_vec;
1115
use identified_vec::identified_vec::IdentifiedVec;
1216
use identified_vec::identifiable::Identifiable;
1317
use identified_vec::identified_vec_of::IdentifiedVecOf;
18+
use std::cell::RefCell;
1419

15-
#[derive(Eq, PartialEq, Clone, Debug, Hash)]
20+
#[derive(Eq, PartialEq, Clone, Debug)]
1621
struct User {
1722
id: &'static str,
23+
name: RefCell<&'static str>,
1824
}
1925

2026
impl User {
21-
fn new(id: &'static str) -> Self {
22-
Self { id }
27+
fn new(id: &'static str, name: &'static str) -> Self {
28+
Self {
29+
id,
30+
name: RefCell::new(name),
31+
}
32+
}
33+
fn name(&self) -> &'static str {
34+
*self.name.borrow()
2335
}
2436
}
2537

@@ -30,12 +42,85 @@ impl Identifiable for User {
3042
}
3143
}
3244

33-
let users = IdentifiedVecOf::<User>::from_iter([
34-
User::new("u_42"),
35-
User::new("u_1729")
45+
let mut users = IdentifiedVecOf::<User>::from_iter([
46+
User::new("u_42", "Satoshi Nakamoto"),
47+
User::new("u_1337", "Leia Skywalker"),
3648
]);
3749

38-
assert_eq!(users.index_of_id(&"u_1729"), Some(1));
50+
assert_eq!(
51+
users.get(&"u_42").map(|u| u.name()),
52+
Some("Satoshi Nakamoto")
53+
);
54+
55+
assert_eq!(
56+
users.get_at_index(1).map(|u| u.name()),
57+
Some("Leia Skywalker")
58+
);
59+
60+
users.append(User::new("u_237", "Alan Turing"));
61+
assert_eq!(
62+
users.elements(),
63+
[
64+
User::new("u_42", "Satoshi Nakamoto"),
65+
User::new("u_1337", "Leia Skywalker"),
66+
User::new("u_237", "Alan Turing"),
67+
]
68+
.iter()
69+
.collect::<Vec<&User>>()
70+
);
71+
72+
// Element with same ID is not appended:
73+
users.append(User::new("u_42", "Tom Mervolo Dolder"));
74+
assert_eq!(
75+
users.elements(),
76+
[
77+
User::new("u_42", "Satoshi Nakamoto"),
78+
User::new("u_1337", "Leia Skywalker"),
79+
User::new("u_237", "Alan Turing"),
80+
]
81+
.iter()
82+
.collect::<Vec<&User>>()
83+
);
84+
85+
// Element with same ID replaces existing if an `update_*` method is used:
86+
// e.g. `update_or_insert`:
87+
users.update_or_insert(User::new("u_42", "Tom Mervolo Dolder"), 0);
88+
assert_eq!(
89+
users.elements(),
90+
[
91+
User::new("u_42", "Tom Mervolo Dolder"),
92+
User::new("u_1337", "Leia Skywalker"),
93+
User::new("u_237", "Alan Turing"),
94+
]
95+
.iter()
96+
.collect::<Vec<&User>>()
97+
);
98+
99+
// or `update_or_append`
100+
users.update_or_append(User::new("u_237", "Marie Curie"));
101+
assert_eq!(
102+
users.elements(),
103+
[
104+
User::new("u_42", "Tom Mervolo Dolder"),
105+
User::new("u_1337", "Leia Skywalker"),
106+
User::new("u_237", "Marie Curie"),
107+
]
108+
.iter()
109+
.collect::<Vec<&User>>()
110+
);
111+
112+
// or mutate with `get_mut(id)`
113+
*users.get_mut(&"u_1337").unwrap().name.get_mut() = "Yoda";
114+
assert_eq!(
115+
users.elements(),
116+
[
117+
User::new("u_42", "Tom Mervolo Dolder"),
118+
User::new("u_1337", "Yoda"),
119+
User::new("u_237", "Marie Curie"),
120+
]
121+
.iter()
122+
.collect::<Vec<&User>>()
123+
);
39124
```
40125

41126
Or you can provide a closure that describes an element's identity:

src/identified_vec.rs

Lines changed: 88 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,15 +36,23 @@ pub enum ConflictResolutionChoice {
3636
/// use identified_vec::identified_vec::IdentifiedVec;
3737
/// use identified_vec::identifiable::Identifiable;
3838
/// use identified_vec::identified_vec_of::IdentifiedVecOf;
39+
/// use std::cell::RefCell;
3940
///
40-
/// #[derive(Eq, PartialEq, Clone, Debug, Hash)]
41+
/// #[derive(Eq, PartialEq, Clone, Debug)]
4142
/// struct User {
4243
/// id: &'static str,
44+
/// name: RefCell<&'static str>,
4345
/// }
4446
///
4547
/// impl User {
46-
/// fn new(id: &'static str) -> Self {
47-
/// Self { id }
48+
/// fn new(id: &'static str, name: &'static str) -> Self {
49+
/// Self {
50+
/// id,
51+
/// name: RefCell::new(name),
52+
/// }
53+
/// }
54+
/// fn name(&self) -> &'static str {
55+
/// *self.name.borrow()
4856
/// }
4957
/// }
5058
///
@@ -55,10 +63,83 @@ pub enum ConflictResolutionChoice {
5563
/// }
5664
/// }
5765
///
58-
/// let mut users =
59-
/// IdentifiedVecOf::<User>::from_iter([User::new("u_42"), User::new("u_1729")]);
66+
/// let mut users = IdentifiedVecOf::<User>::from_iter([
67+
/// User::new("u_42", "Satoshi Nakamoto"),
68+
/// User::new("u_1337", "Leia Skywalker"),
69+
/// ]);
70+
///
71+
/// assert_eq!(
72+
/// users.get(&"u_42").map(|u| u.name()),
73+
/// Some("Satoshi Nakamoto")
74+
/// );
75+
/// assert_eq!(
76+
/// users.get_at_index(1).map(|u| u.name()),
77+
/// Some("Leia Skywalker")
78+
/// );
79+
/// users.append(User::new("u_237", "Alan Turing"));
80+
/// assert_eq!(
81+
/// users.elements(),
82+
/// [
83+
/// User::new("u_42", "Satoshi Nakamoto"),
84+
/// User::new("u_1337", "Leia Skywalker"),
85+
/// User::new("u_237", "Alan Turing"),
86+
/// ]
87+
/// .iter()
88+
/// .collect::<Vec<&User>>()
89+
/// );
90+
///
91+
/// // Element with same ID is not appended:
92+
/// users.append(User::new("u_42", "Tom Mervolo Dolder"));
93+
/// assert_eq!(
94+
/// users.elements(),
95+
/// [
96+
/// User::new("u_42", "Satoshi Nakamoto"),
97+
/// User::new("u_1337", "Leia Skywalker"),
98+
/// User::new("u_237", "Alan Turing"),
99+
/// ]
100+
/// .iter()
101+
/// .collect::<Vec<&User>>()
102+
/// );
103+
///
104+
/// // Element with same ID replaces existing if an `update_*` method is used:
105+
/// // e.g. `update_or_insert`:
106+
/// users.update_or_insert(User::new("u_42", "Tom Mervolo Dolder"), 0);
107+
/// assert_eq!(
108+
/// users.elements(),
109+
/// [
110+
/// User::new("u_42", "Tom Mervolo Dolder"),
111+
/// User::new("u_1337", "Leia Skywalker"),
112+
/// User::new("u_237", "Alan Turing"),
113+
/// ]
114+
/// .iter()
115+
/// .collect::<Vec<&User>>()
116+
/// );
117+
///
118+
/// // or `update_or_append`
119+
/// users.update_or_append(User::new("u_237", "Marie Curie"));
120+
/// assert_eq!(
121+
/// users.elements(),
122+
/// [
123+
/// User::new("u_42", "Tom Mervolo Dolder"),
124+
/// User::new("u_1337", "Leia Skywalker"),
125+
/// User::new("u_237", "Marie Curie"),
126+
/// ]
127+
/// .iter()
128+
/// .collect::<Vec<&User>>()
129+
/// );
60130
///
61-
/// assert_eq!(users.index_of_id(&"u_1729"), Some(1));
131+
/// // or mutate with `get_mut(id)`
132+
/// *users.get_mut(&"u_1337").unwrap().name.get_mut() = "Yoda";
133+
/// assert_eq!(
134+
/// users.elements(),
135+
/// [
136+
/// User::new("u_42", "Tom Mervolo Dolder"),
137+
/// User::new("u_1337", "Yoda"),
138+
/// User::new("u_237", "Marie Curie"),
139+
/// ]
140+
/// .iter()
141+
/// .collect::<Vec<&User>>()
142+
/// );
62143
/// ```
63144
///
64145
/// Or you can provide a closure that describes an element's identity:
@@ -796,7 +877,7 @@ where
796877
#[cfg(test)]
797878
mod tests {
798879

799-
use std::{cell::RefCell, collections::HashSet, fmt::Debug};
880+
use std::{cell::RefCell, collections::HashSet, fmt::Debug, ops::Deref};
800881

801882
use crate::{
802883
identifiable::Identifiable,

0 commit comments

Comments
 (0)