Skip to content

Commit

Permalink
Separate the lifetimes of each input of OrdMap::diff and OrdSet::diff (
Browse files Browse the repository at this point in the history
…#42)

This is a breaking change but only for code that uses turbofish syntax
on the `diff` method, the `DiffIter` type, or the `DiffItem` type.

Adapted from `im` PR #168.

Co-authored-by: Joe Neeman <[email protected]>

Co-authored-by: Simon Sapin <[email protected]>
  • Loading branch information
jneem and SimonSapin authored Nov 26, 2021
1 parent 9347e5a commit 94e30ef
Show file tree
Hide file tree
Showing 3 changed files with 29 additions and 26 deletions.
27 changes: 15 additions & 12 deletions src/nodes/btree.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1345,22 +1345,22 @@ impl<A: BTreeValue + Clone> ExactSizeIterator for ConsumingIter<A> {}
// DiffIter

/// An iterator over the differences between two ordered sets.
pub struct DiffIter<'a, A> {
pub struct DiffIter<'a, 'b, A> {
old_stack: Vec<IterItem<'a, A>>,
new_stack: Vec<IterItem<'a, A>>,
new_stack: Vec<IterItem<'b, A>>,
}

/// A description of a difference between two ordered sets.
#[derive(PartialEq, Eq, Debug)]
pub enum DiffItem<'a, A> {
pub enum DiffItem<'a, 'b, A> {
/// This value has been added to the new set.
Add(&'a A),
Add(&'b A),
/// This value has been changed between the two sets.
Update {
/// The old value.
old: &'a A,
/// The new value.
new: &'a A,
new: &'b A,
},
/// This value has been removed from the new set.
Remove(&'a A),
Expand All @@ -1371,8 +1371,8 @@ enum IterItem<'a, A> {
Yield(&'a A),
}

impl<'a, A: 'a> DiffIter<'a, A> {
pub(crate) fn new(old: &'a Node<A>, new: &'a Node<A>) -> Self {
impl<'a, 'b, A: 'a + 'b> DiffIter<'a, 'b, A> {
pub(crate) fn new(old: &'a Node<A>, new: &'b Node<A>) -> Self {
DiffIter {
old_stack: if old.keys.is_empty() {
Vec::new()
Expand All @@ -1387,13 +1387,16 @@ impl<'a, A: 'a> DiffIter<'a, A> {
}
}

fn push_node(stack: &mut Vec<IterItem<'a, A>>, maybe_node: &'a Option<PoolRef<Node<A>>>) {
fn push_node<'either>(
stack: &mut Vec<IterItem<'either, A>>,
maybe_node: &'either Option<PoolRef<Node<A>>>,
) {
if let Some(node) = maybe_node {
stack.push(IterItem::Consider(node))
}
}

fn push(stack: &mut Vec<IterItem<'a, A>>, node: &'a Node<A>) {
fn push<'either>(stack: &mut Vec<IterItem<'either, A>>, node: &'either Node<A>) {
for n in 0..node.keys.len() {
let i = node.keys.len() - n;
Self::push_node(stack, &node.children[i]);
Expand All @@ -1403,11 +1406,11 @@ impl<'a, A: 'a> DiffIter<'a, A> {
}
}

impl<'a, A> Iterator for DiffIter<'a, A>
impl<'a, 'b, A> Iterator for DiffIter<'a, 'b, A>
where
A: 'a + BTreeValue + PartialEq,
A: 'a + 'b + BTreeValue + PartialEq,
{
type Item = DiffItem<'a, A>;
type Item = DiffItem<'a, 'b, A>;

fn next(&mut self) -> Option<Self::Item> {
loop {
Expand Down
18 changes: 9 additions & 9 deletions src/ord/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ where
/// the two maps, minus the number of elements belonging to nodes
/// shared between them)
#[must_use]
pub fn diff<'a>(&'a self, other: &'a Self) -> DiffIter<'a, K, V> {
pub fn diff<'a, 'b>(&'a self, other: &'b Self) -> DiffIter<'a, 'b, K, V> {
DiffIter {
it: NodeDiffIter::new(&self.root, &other.root),
}
Expand Down Expand Up @@ -1884,31 +1884,31 @@ where
impl<'a, K, V> ExactSizeIterator for Iter<'a, K, V> where (K, V): 'a + BTreeValue {}

/// An iterator over the differences between two maps.
pub struct DiffIter<'a, K, V> {
it: NodeDiffIter<'a, (K, V)>,
pub struct DiffIter<'a, 'b, K, V> {
it: NodeDiffIter<'a, 'b, (K, V)>,
}

/// A description of a difference between two ordered maps.
#[derive(PartialEq, Eq, Debug)]
pub enum DiffItem<'a, K, V> {
pub enum DiffItem<'a, 'b, K, V> {
/// This value has been added to the new map.
Add(&'a K, &'a V),
Add(&'b K, &'b V),
/// This value has been changed between the two maps.
Update {
/// The old value.
old: (&'a K, &'a V),
/// The new value.
new: (&'a K, &'a V),
new: (&'b K, &'b V),
},
/// This value has been removed from the new map.
Remove(&'a K, &'a V),
}

impl<'a, K, V> Iterator for DiffIter<'a, K, V>
impl<'a, 'b, K, V> Iterator for DiffIter<'a, 'b, K, V>
where
(K, V): 'a + BTreeValue + PartialEq,
(K, V): 'a + 'b + BTreeValue + PartialEq,
{
type Item = DiffItem<'a, K, V>;
type Item = DiffItem<'a, 'b, K, V>;

fn next(&mut self) -> Option<Self::Item> {
self.it.next().map(|item| match item {
Expand Down
10 changes: 5 additions & 5 deletions src/ord/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,7 @@ where
/// the two sets, minus the number of elements belonging to nodes
/// shared between them)
#[must_use]
pub fn diff<'a>(&'a self, other: &'a Self) -> DiffIter<'_, A> {
pub fn diff<'a, 'b>(&'a self, other: &'b Self) -> DiffIter<'a, 'b, A> {
DiffIter {
it: NodeDiffIter::new(&self.root, &other.root),
}
Expand Down Expand Up @@ -1028,15 +1028,15 @@ where
}

/// An iterator over the difference between two sets.
pub struct DiffIter<'a, A> {
it: NodeDiffIter<'a, Value<A>>,
pub struct DiffIter<'a, 'b, A> {
it: NodeDiffIter<'a, 'b, Value<A>>,
}

impl<'a, A> Iterator for DiffIter<'a, A>
impl<'a, 'b, A> Iterator for DiffIter<'a, 'b, A>
where
A: Ord + PartialEq,
{
type Item = DiffItem<'a, A>;
type Item = DiffItem<'a, 'b, A>;

/// Advance the iterator and return the next value.
///
Expand Down

0 comments on commit 94e30ef

Please sign in to comment.