schema_registry_api/domain/subject/
name.rs

1use std::fmt::Display;
2use std::ops::Deref;
3use std::str::FromStr;
4
5use crate::SubjectNameError;
6
7/// A subject name
8///
9/// You can build the schema id from a string
10///
11/// ```rust
12/// # use schema_registry_api::SubjectName;
13/// let a_topic_value = "a-topic-value".parse::<SubjectName>().expect("Should be a valid name");
14/// let a_topic_key = "a-topic-key".parse::<SubjectName>().expect("Should be a valid name");
15/// ```
16///
17/// Note that name could not contains control characters
18///
19/// ```rust
20/// #  use schema_registry_api::SubjectName;
21/// let result = "\n".parse::<SubjectName>(); // 🚨 Error
22/// assert!(result.is_err());
23/// ```
24///
25#[derive(Debug, Clone, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize)]
26pub struct SubjectName(String);
27
28impl AsRef<str> for SubjectName {
29    fn as_ref(&self) -> &str {
30        self.0.as_str()
31    }
32}
33
34impl Deref for SubjectName {
35    type Target = String;
36
37    fn deref(&self) -> &Self::Target {
38        &self.0
39    }
40}
41
42impl FromStr for SubjectName {
43    type Err = SubjectNameError;
44
45    fn from_str(s: &str) -> Result<Self, Self::Err> {
46        if s.is_empty() {
47            return Err(Self::Err::EmptyName);
48        }
49        if s.chars().any(char::is_control) {
50            return Err(Self::Err::InvalidChar(s.to_string()));
51        }
52        Ok(Self(s.to_string()))
53    }
54}
55
56impl Display for SubjectName {
57    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
58        write!(f, "{}", self.0)
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use assert2::{check, let_assert};
65
66    use super::*;
67
68    #[test]
69    fn should_parse_subject_name() {
70        let name = "plop";
71        let result = name.parse::<SubjectName>();
72        let_assert!(Ok(subject) = result);
73        check!(subject.as_ref() == name);
74        check!(subject.to_lowercase() == name);
75    }
76
77    #[test]
78    fn should_not_parse_empty_subject_name() {
79        let name = "";
80        let result = name.parse::<SubjectName>();
81        let_assert!(Err(SubjectNameError::EmptyName) = result);
82    }
83
84    #[test]
85    fn should_not_parse_bad_subject_name() {
86        let name = "\nasd";
87        let result = name.parse::<SubjectName>();
88        let_assert!(Err(SubjectNameError::InvalidChar(_)) = result);
89    }
90}