Skip to main content

made_core/value_objects/
proposal_content.rs

1use std::fmt;
2use std::ops::Deref;
3
4use serde::{Deserialize, Serialize};
5
6/// Provider-authored proposal text.
7///
8/// Non-emptiness is an aggregate invariant enforced by `Proposal`; this value
9/// object gives the port boundary a semantic type before aggregate creation.
10#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
11#[serde(transparent)]
12pub struct ProposalContent(String);
13
14impl ProposalContent {
15    #[must_use]
16    pub fn new(raw: impl Into<String>) -> Self {
17        Self(raw.into())
18    }
19
20    #[must_use]
21    pub fn as_str(&self) -> &str {
22        &self.0
23    }
24}
25
26impl From<String> for ProposalContent {
27    fn from(value: String) -> Self {
28        Self::new(value)
29    }
30}
31
32impl From<&str> for ProposalContent {
33    fn from(value: &str) -> Self {
34        Self::new(value)
35    }
36}
37
38impl Deref for ProposalContent {
39    type Target = str;
40
41    fn deref(&self) -> &Self::Target {
42        self.as_str()
43    }
44}
45
46impl fmt::Display for ProposalContent {
47    fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
48        formatter.write_str(self.as_str())
49    }
50}
51
52impl PartialEq<str> for ProposalContent {
53    fn eq(&self, other: &str) -> bool {
54        self.as_str() == other
55    }
56}
57
58impl PartialEq<&str> for ProposalContent {
59    fn eq(&self, other: &&str) -> bool {
60        self.as_str() == *other
61    }
62}