Impl new fn CrateName::dedup

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
This commit is contained in:
Jiahao XU 2022-08-02 22:14:05 +10:00
parent 58c50cbe91
commit 09c1afe616
No known key found for this signature in database
GPG key ID: 591C0B03040416D6

View file

@ -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<String>,
@ -37,3 +37,71 @@ impl FromStr for CrateName {
})
}
}
impl CrateName {
pub fn dedup(mut crate_names: Vec<Self>) -> impl Iterator<Item = Self> {
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<CrateName> = 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")]
);
}
}