Skip to main content

ephemeris_forge/
name_set.rs

1//! comparison and write.
2
3use std::vec;
4
5const PATTERN_SEPARATOR: &str = ";";
6
7/// Names, sorted and deduplicated on construction.
8#[derive(Clone, Debug, Default, Eq, PartialEq)]
9pub struct NameSet(Vec<String>);
10
11impl NameSet {
12    /// Sort and deduplicate `values` into their comparison and write order.
13    #[must_use]
14    pub fn new<V: IntoIterator<Item = String>>(values: V) -> Self {
15        let mut values: Vec<String> = values.into_iter().collect();
16        values.sort_unstable();
17        values.dedup();
18        Self(values)
19    }
20
21    /// Split a semicolon separated pattern list, dropping empty parts.
22    #[must_use]
23    pub fn from_patterns(patterns: &str) -> Self {
24        Self::new(
25            patterns
26                .split(PATTERN_SEPARATOR)
27                .filter(|pattern| !pattern.is_empty())
28                .map(str::to_owned),
29        )
30    }
31
32    /// Join the names into a semicolon separated pattern list.
33    #[must_use]
34    pub fn to_patterns(&self) -> String {
35        self.0.join(PATTERN_SEPARATOR)
36    }
37
38    /// Borrow the names in their canonical order.
39    #[must_use]
40    pub fn as_slice(&self) -> &[String] {
41        &self.0
42    }
43
44    /// Take ownership of the names in their canonical order.
45    #[must_use]
46    pub fn into_vec(self) -> Vec<String> {
47        self.0
48    }
49}
50
51impl IntoIterator for NameSet {
52    type IntoIter = vec::IntoIter<String>;
53    type Item = String;
54
55    fn into_iter(self) -> Self::IntoIter {
56        self.0.into_iter()
57    }
58}
59
60#[cfg(test)]
61mod tests {
62    use super::NameSet;
63
64    #[test]
65    fn construction_sorts_and_deduplicates() {
66        let names = NameSet::new(["b".to_owned(), "a".to_owned(), "a".to_owned()]);
67        assert_eq!(names.as_slice(), ["a", "b"]);
68    }
69
70    #[test]
71    fn patterns_split_and_join_as_a_set() {
72        let names = NameSet::from_patterns("b;;a;a;");
73        assert_eq!(names.as_slice(), ["a", "b"]);
74        assert_eq!(names.to_patterns(), "a;b");
75    }
76}