acton_ern/model/
part.rs

1use std::borrow::Cow;
2use std::fmt;
3
4use derive_more::{AsRef, Into};
5
6use crate::errors::ErnError;
7
8#[derive(AsRef, Into, Eq, Debug, PartialEq, Clone, Hash, PartialOrd)]
9pub struct Part(pub(crate) String);
10
11impl Part {
12    pub fn as_str(&self) -> &str {
13        &self.0
14    }
15
16    pub fn into_owned(self) -> Part {
17        Part(self.0.to_string())
18    }
19
20    pub fn new(value: impl Into<String>) -> Result<Part, ErnError> {
21        let value = value.into();
22        if value.contains(':') || value.contains('/') {
23            return Err(ErnError::InvalidPartFormat);
24        }
25        if value.is_empty() {
26            return Err(ErnError::ParseFailure(
27                "Part",
28                "cannot be empty".to_string(),
29            ));
30        }
31        Ok(Part(value))
32    }
33}
34
35impl fmt::Display for Part {
36    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
37        write!(f, "{}", self.0)
38    }
39}
40
41impl std::str::FromStr for Part {
42    type Err = ErnError;
43    fn from_str(s: &str) -> Result<Self, Self::Err> {
44        Part::new(Cow::Owned(s.to_owned()))
45    }
46}
47
48// impl From<Part> for String {
49//     fn from(part: Part) -> Self {
50//         part.0
51//     }
52// }
53
54#[cfg(test)]
55mod tests {
56    use super::*;
57
58    #[test]
59    fn test_part_creation() -> anyhow::Result<()> {
60        let part = Part::new("segment")?;
61        assert_eq!(part.as_str(), "segment");
62        Ok(())
63    }
64
65    #[test]
66    fn test_part_display() -> anyhow::Result<()> {
67        let part = Part::new("example")?;
68        assert_eq!(format!("{}", part), "example");
69        Ok(())
70    }
71
72    #[test]
73    fn test_part_from_str() {
74        let part: Part = "test".parse().unwrap();
75        assert_eq!(part.as_str(), "test");
76    }
77
78    #[test]
79    fn test_part_equality() -> anyhow::Result<()> {
80        let part1 = Part::new("segment1")?;
81        let part2 = Part::new("segment1")?;
82        let part3 = Part::new("segment2")?;
83        assert_eq!(part1, part2);
84        assert_ne!(part1, part3);
85        Ok(())
86    }
87
88    #[test]
89    fn test_part_into_string() -> anyhow::Result<()> {
90        let part = Part::new("segment")?;
91        let string: String = part.into();
92        assert_eq!(string, "segment");
93        Ok(())
94    }
95}