Skip to main content

mocari/core/
ids.rs

1use std::fmt;
2use std::str::FromStr;
3
4use crate::{Error, Result};
5
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7pub struct Id(String);
8
9impl Id {
10    pub fn new(value: impl Into<String>) -> Result<Self> {
11        let value = value.into();
12        if value.is_empty() {
13            return Err(Error::EmptyId);
14        }
15
16        Ok(Self(value))
17    }
18
19    pub fn as_str(&self) -> &str {
20        &self.0
21    }
22}
23
24impl fmt::Display for Id {
25    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
26        formatter.write_str(self.as_str())
27    }
28}
29
30impl FromStr for Id {
31    type Err = Error;
32
33    fn from_str(value: &str) -> Result<Self> {
34        Self::new(value)
35    }
36}
37
38macro_rules! typed_id {
39    ($name:ident) => {
40        #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
41        pub struct $name(Id);
42
43        impl $name {
44            pub fn new(value: impl Into<String>) -> Result<Self> {
45                Id::new(value).map(Self)
46            }
47
48            pub fn as_str(&self) -> &str {
49                self.0.as_str()
50            }
51        }
52
53        impl fmt::Display for $name {
54            fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
55                formatter.write_str(self.as_str())
56            }
57        }
58
59        impl FromStr for $name {
60            type Err = Error;
61
62            fn from_str(value: &str) -> Result<Self> {
63                Self::new(value)
64            }
65        }
66    };
67}
68
69typed_id!(ParameterId);
70typed_id!(PartId);
71typed_id!(DrawableId);