Skip to main content

made_core/value_objects/
council_journal_consumer.rs

1use serde::{Deserialize, Serialize};
2
3use crate::error::DomainError;
4
5/// Stable name of one independent consumer of the council journal.
6#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
7#[serde(try_from = "String", into = "String")]
8pub struct CouncilJournalConsumer(String);
9
10impl CouncilJournalConsumer {
11    pub const MAX_LEN: usize = 128;
12
13    pub fn new(value: impl Into<String>) -> Result<Self, DomainError> {
14        let value = value.into();
15        let value = value.trim();
16        if value.is_empty() {
17            return Err(DomainError::EmptyField {
18                field: "council_journal_consumer",
19            });
20        }
21        if value.len() > Self::MAX_LEN {
22            return Err(DomainError::FieldTooLong {
23                field: "council_journal_consumer",
24                actual: value.len(),
25                max: Self::MAX_LEN,
26            });
27        }
28        if !value
29            .chars()
30            .all(|ch| ch.is_ascii_alphanumeric() || matches!(ch, '-' | '_' | '.' | ':' | '/'))
31        {
32            return Err(DomainError::InvalidCharacters {
33                field: "council_journal_consumer",
34            });
35        }
36        Ok(Self(value.to_owned()))
37    }
38
39    #[must_use]
40    pub fn as_str(&self) -> &str {
41        &self.0
42    }
43}
44
45impl TryFrom<String> for CouncilJournalConsumer {
46    type Error = DomainError;
47    fn try_from(value: String) -> Result<Self, Self::Error> {
48        Self::new(value)
49    }
50}
51impl From<CouncilJournalConsumer> for String {
52    fn from(value: CouncilJournalConsumer) -> Self {
53        value.0
54    }
55}