made_core/value_objects/
council_contract_id.rs1use std::fmt;
2
3use serde::{Deserialize, Serialize};
4
5use crate::error::DomainError;
6
7const MAX_COUNCIL_CONTRACT_ID_LEN: usize = 128;
8
9#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
11#[serde(transparent)]
12pub struct CouncilContractId(String);
13
14impl CouncilContractId {
15 pub fn new(raw: impl Into<String>) -> Result<Self, DomainError> {
16 let raw = raw.into();
17 let value = raw.trim();
18 if value.is_empty() {
19 return Err(DomainError::EmptyField {
20 field: "task_metadata.council_contract_id",
21 });
22 }
23 if value.len() > MAX_COUNCIL_CONTRACT_ID_LEN {
24 return Err(DomainError::FieldTooLong {
25 field: "task_metadata.council_contract_id",
26 actual: value.len(),
27 max: MAX_COUNCIL_CONTRACT_ID_LEN,
28 });
29 }
30 Ok(Self(value.to_owned()))
31 }
32
33 #[must_use]
34 pub fn as_str(&self) -> &str {
35 &self.0
36 }
37}
38
39impl fmt::Display for CouncilContractId {
40 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
41 formatter.write_str(self.as_str())
42 }
43}
44
45impl PartialEq<str> for CouncilContractId {
46 fn eq(&self, other: &str) -> bool {
47 self.as_str() == other
48 }
49}
50
51impl PartialEq<&str> for CouncilContractId {
52 fn eq(&self, other: &&str) -> bool {
53 self.as_str() == *other
54 }
55}
56
57#[cfg(test)]
58mod tests {
59 use super::*;
60
61 #[test]
62 fn trims_valid_identity() {
63 assert_eq!(
64 CouncilContractId::new(" council-v1 ").unwrap(),
65 "council-v1"
66 );
67 }
68
69 #[test]
70 fn rejects_empty_identity() {
71 assert!(CouncilContractId::new(" ").is_err());
72 }
73}