From 09c1afe616a670f7f9c4a300474381fcdb7c5be8 Mon Sep 17 00:00:00 2001 From: Jiahao XU Date: Tue, 2 Aug 2022 22:14:05 +1000 Subject: [PATCH] Impl new fn `CrateName::dedup` Signed-off-by: Jiahao XU --- src/helpers/crate_name.rs | 76 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/src/helpers/crate_name.rs b/src/helpers/crate_name.rs index 58ef59c0..7c38e8f5 100644 --- a/src/helpers/crate_name.rs +++ b/src/helpers/crate_name.rs @@ -1,8 +1,8 @@ -use std::convert::Infallible; -use std::fmt; -use std::str::FromStr; +use std::{convert::Infallible, fmt, str::FromStr}; -#[derive(Debug, Clone)] +use itertools::Itertools; + +#[derive(Debug, Clone, Eq, PartialEq)] pub struct CrateName { pub name: String, pub version: Option, @@ -37,3 +37,71 @@ impl FromStr for CrateName { }) } } + +impl CrateName { + pub fn dedup(mut crate_names: Vec) -> impl Iterator { + crate_names.sort_by(|x, y| x.name.cmp(&y.name)); + crate_names.into_iter().coalesce(|previous, current| { + if previous.name == current.name { + Ok(current) + } else { + Err((previous, current)) + } + }) + } +} + +#[cfg(test)] +mod tests { + use super::*; + + macro_rules! assert_dedup { + ([ $( ( $input_name:expr, $input_version:expr ) ),* ], [ $( ( $output_name:expr, $output_version:expr ) ),* ]) => { + let input_crate_names = vec![$( CrateName { + name: $input_name.into(), + version: Some($input_version.into()) + }, )*]; + + let mut output_crate_names: Vec = vec![$( CrateName { + name: $output_name.into(), version: Some($output_version.into()) + }, )*]; + output_crate_names.sort_by(|x, y| x.name.cmp(&y.name)); + + let crate_names: Vec<_> = CrateName::dedup(input_crate_names).collect(); + assert_eq!(crate_names, output_crate_names); + }; + } + + #[test] + fn test_dedup() { + // Base case 0: Empty input + assert_dedup!([], []); + + // Base case 1: With only one input + assert_dedup!([("a", "1")], [("a", "1")]); + + // Base Case 2: Only has duplicate names + assert_dedup!([("a", "1"), ("a", "2")], [("a", "2")]); + + // Complex Case 0: Having two crates + assert_dedup!( + [("a", "10"), ("b", "3"), ("a", "0"), ("b", "0"), ("a", "1")], + [("a", "1"), ("b", "0")] + ); + + // Complex Case 1: Having three crates + assert_dedup!( + [ + ("d", "1.1"), + ("a", "10"), + ("b", "3"), + ("d", "230"), + ("a", "0"), + ("b", "0"), + ("a", "1"), + ("d", "23") + ], + [("a", "1"), ("b", "0"), ("d", "23")] + ); + } +}