1use alloc::string::String;
13use alloc::vec::Vec;
14
15use crate::error::ProfileError;
16
17#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
20pub struct KeyId(Vec<u8>);
21
22impl KeyId {
23 pub fn from_text(id: &str) -> Result<Self, ProfileError> {
29 Self::from_bytes(id.as_bytes().to_vec())
30 }
31
32 pub fn from_bytes(id: Vec<u8>) -> Result<Self, ProfileError> {
37 if id.is_empty() || id.len() > 128 {
38 return Err(ProfileError::KeyIdLength { actual: id.len() });
39 }
40 Ok(Self(id))
41 }
42
43 #[must_use]
45 pub fn as_catalog_name(&self) -> Option<&str> {
46 core::str::from_utf8(&self.0).ok()
47 }
48
49 #[must_use]
51 pub fn as_bytes(&self) -> &[u8] {
52 &self.0
53 }
54}
55
56#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
58pub struct MessageId(Vec<u8>);
59
60impl MessageId {
61 pub fn from_bytes(id: Vec<u8>) -> Result<Self, ProfileError> {
66 if id.is_empty() || id.len() > 64 {
67 return Err(ProfileError::MessageIdLength { actual: id.len() });
68 }
69 Ok(Self(id))
70 }
71
72 #[must_use]
74 pub fn as_bytes(&self) -> &[u8] {
75 &self.0
76 }
77}
78
79#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
81pub struct Subject(String);
82
83impl Subject {
84 pub fn new(subject: String) -> Result<Self, ProfileError> {
89 if subject.is_empty() {
90 return Err(ProfileError::EmptySubject);
91 }
92 Ok(Self(subject))
93 }
94
95 #[must_use]
97 pub fn as_str(&self) -> &str {
98 &self.0
99 }
100}
101
102#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
104pub struct ResponseSubject(String);
105
106impl ResponseSubject {
107 pub fn new(subject: String) -> Result<Self, ProfileError> {
112 if subject.is_empty() {
113 return Err(ProfileError::EmptySubject);
114 }
115 Ok(Self(subject))
116 }
117
118 #[must_use]
120 pub fn as_str(&self) -> &str {
121 &self.0
122 }
123}
124
125#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
132pub struct ContentType(String);
133
134impl ContentType {
135 pub fn new(content_type: String) -> Result<Self, ProfileError> {
141 if content_type.is_empty()
142 || content_type.trim() != content_type
143 || content_type.matches('/').count() != 1
144 {
145 return Err(ProfileError::ContentTypeForm);
146 }
147 Ok(Self(content_type))
148 }
149
150 #[must_use]
152 pub fn as_str(&self) -> &str {
153 &self.0
154 }
155}
156
157#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
159pub struct UnixTime(pub i64);
160
161#[derive(Debug, Clone, PartialEq, Eq)]
164pub struct ExternalAad(Vec<u8>);
165
166impl ExternalAad {
167 #[must_use]
169 pub const fn empty() -> Self {
170 Self(Vec::new())
171 }
172
173 #[must_use]
175 pub const fn from_bytes(bytes: Vec<u8>) -> Self {
176 Self(bytes)
177 }
178
179 #[must_use]
181 pub fn as_bytes(&self) -> &[u8] {
182 &self.0
183 }
184}
185
186#[derive(Debug, Clone, PartialEq, Eq)]
188pub struct SealedAad {
189 pub signature: ExternalAad,
191 pub encryption: ExternalAad,
193}
194
195impl SealedAad {
196 #[must_use]
198 pub const fn empty() -> Self {
199 Self {
200 signature: ExternalAad::empty(),
201 encryption: ExternalAad::empty(),
202 }
203 }
204}
205
206#[derive(Debug, Clone, PartialEq, Eq)]
208pub struct Signature(Vec<u8>);
209
210impl Signature {
211 pub fn from_bytes(bytes: Vec<u8>) -> Result<Self, ProfileError> {
216 if bytes.is_empty() {
217 return Err(ProfileError::EmptySignature);
218 }
219 Ok(Self(bytes))
220 }
221
222 #[must_use]
224 pub fn as_bytes(&self) -> &[u8] {
225 &self.0
226 }
227}
228
229#[derive(Debug, Clone, PartialEq, Eq)]
231pub struct CoseBytes(Vec<u8>);
232
233impl CoseBytes {
234 pub(crate) const fn new(bytes: Vec<u8>) -> Self {
235 Self(bytes)
236 }
237
238 #[must_use]
240 pub fn as_bytes(&self) -> &[u8] {
241 &self.0
242 }
243
244 #[must_use]
246 pub fn into_vec(self) -> Vec<u8> {
247 self.0
248 }
249}
250
251impl AsRef<[u8]> for CoseBytes {
252 fn as_ref(&self) -> &[u8] {
253 &self.0
254 }
255}