From 178267c701c233542078c09fe6b19802f9642dbd Mon Sep 17 00:00:00 2001 From: HampusM Date: Mon, 30 Jan 2023 21:29:21 +0100 Subject: feat: improve macro error messages --- macros/src/util/iterator_ext.rs | 42 +++++++++++++++++++++++++++++------------ 1 file changed, 30 insertions(+), 12 deletions(-) (limited to 'macros/src/util/iterator_ext.rs') diff --git a/macros/src/util/iterator_ext.rs b/macros/src/util/iterator_ext.rs index 5001068..17482ae 100644 --- a/macros/src/util/iterator_ext.rs +++ b/macros/src/util/iterator_ext.rs @@ -1,26 +1,39 @@ -use std::collections::HashMap; +use std::collections::HashSet; use std::hash::Hash; +/// [`Iterator`] extension trait. pub trait IteratorExt +where + Item: Eq + Hash, { - fn find_duplicate(&mut self) -> Option; + /// Finds the first occurance of a duplicate item. + /// + /// This function is short-circuiting. So it will immedietly return `Some` when + /// it comes across a item it has already seen. + /// + /// The returned tuple contains the first item occurance & the second item occurance. + /// In that specific order. + /// + /// Both items are returned in the case of the hash not being representative of the + /// whole item. + fn find_duplicate(self) -> Option<(Item, Item)>; } impl IteratorExt for Iter where Iter: Iterator, - Iter::Item: Eq + Hash + Clone, + Iter::Item: Eq + Hash, { - fn find_duplicate(&mut self) -> Option + fn find_duplicate(self) -> Option<(Iter::Item, Iter::Item)> { - let mut iterated_item_map = HashMap::::new(); + let mut iterated_item_map = HashSet::::new(); for item in self { - if iterated_item_map.contains_key(&item) { - return Some(item); + if let Some(equal_item) = iterated_item_map.take(&item) { + return Some((item, equal_item)); } - iterated_item_map.insert(item, ()); + iterated_item_map.insert(item); } None @@ -33,7 +46,7 @@ mod tests use super::*; #[test] - fn can_find_duplicate() + fn can_find_dupe() { #[derive(Debug, PartialEq, Eq, Clone, Hash)] struct Fruit @@ -58,9 +71,14 @@ mod tests ] .iter() .find_duplicate(), - Some(&Fruit { - name: "Apple".to_string() - }) + Some(( + &Fruit { + name: "Apple".to_string() + }, + &Fruit { + name: "Apple".to_string() + } + )) ); assert_eq!( -- cgit v1.2.3-18-g5258