der/asn1/
printable_string.rs
1use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
4use core::{fmt, ops::Deref};
5
6macro_rules! impl_printable_string {
7 ($type: ty) => {
8 impl_printable_string!($type,);
9 };
10 ($type: ty, $($li: lifetime)?) => {
11 impl_string_type!($type, $($li),*);
12
13 impl<$($li),*> FixedTag for $type {
14 const TAG: Tag = Tag::PrintableString;
15 }
16
17 impl<$($li),*> fmt::Debug for $type {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(f, "PrintableString({:?})", self.as_str())
20 }
21 }
22 };
23}
24
25#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
55pub struct PrintableStringRef<'a> {
56 inner: StrRef<'a>,
58}
59
60impl<'a> PrintableStringRef<'a> {
61 pub fn new<T>(input: &'a T) -> Result<Self>
63 where
64 T: AsRef<[u8]> + ?Sized,
65 {
66 let input = input.as_ref();
67
68 for &c in input.iter() {
70 match c {
71 b'A'..=b'Z'
72 | b'a'..=b'z'
73 | b'0'..=b'9'
74 | b' '
75 | b'\''
76 | b'('
77 | b')'
78 | b'+'
79 | b','
80 | b'-'
81 | b'.'
82 | b'/'
83 | b':'
84 | b'='
85 | b'?' => (),
86 _ => return Err(Self::TAG.value_error()),
87 }
88 }
89
90 StrRef::from_bytes(input)
91 .map(|inner| Self { inner })
92 .map_err(|_| Self::TAG.value_error())
93 }
94}
95
96impl_printable_string!(PrintableStringRef<'a>, 'a);
97
98impl<'a> Deref for PrintableStringRef<'a> {
99 type Target = StrRef<'a>;
100
101 fn deref(&self) -> &Self::Target {
102 &self.inner
103 }
104}
105impl<'a> From<&PrintableStringRef<'a>> for PrintableStringRef<'a> {
106 fn from(value: &PrintableStringRef<'a>) -> PrintableStringRef<'a> {
107 *value
108 }
109}
110
111impl<'a> From<PrintableStringRef<'a>> for AnyRef<'a> {
112 fn from(printable_string: PrintableStringRef<'a>) -> AnyRef<'a> {
113 AnyRef::from_tag_and_value(Tag::PrintableString, printable_string.inner.into())
114 }
115}
116
117#[cfg(feature = "alloc")]
118pub use self::allocation::PrintableString;
119
120#[cfg(feature = "alloc")]
121mod allocation {
122 use super::PrintableStringRef;
123
124 use crate::{
125 asn1::AnyRef,
126 referenced::{OwnedToRef, RefToOwned},
127 BytesRef, Error, FixedTag, Result, StrOwned, Tag,
128 };
129 use alloc::string::String;
130 use core::{fmt, ops::Deref};
131
132 #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
160 pub struct PrintableString {
161 inner: StrOwned,
163 }
164
165 impl PrintableString {
166 pub fn new<T>(input: &T) -> Result<Self>
168 where
169 T: AsRef<[u8]> + ?Sized,
170 {
171 let input = input.as_ref();
172 PrintableStringRef::new(input)?;
173
174 StrOwned::from_bytes(input)
175 .map(|inner| Self { inner })
176 .map_err(|_| Self::TAG.value_error())
177 }
178 }
179
180 impl_printable_string!(PrintableString);
181
182 impl Deref for PrintableString {
183 type Target = StrOwned;
184
185 fn deref(&self) -> &Self::Target {
186 &self.inner
187 }
188 }
189
190 impl<'a> From<PrintableStringRef<'a>> for PrintableString {
191 fn from(value: PrintableStringRef<'a>) -> PrintableString {
192 let inner =
193 StrOwned::from_bytes(value.inner.as_bytes()).expect("Invalid PrintableString");
194 Self { inner }
195 }
196 }
197
198 impl<'a> From<&'a PrintableString> for AnyRef<'a> {
199 fn from(printable_string: &'a PrintableString) -> AnyRef<'a> {
200 AnyRef::from_tag_and_value(
201 Tag::PrintableString,
202 BytesRef::new(printable_string.inner.as_bytes()).expect("Invalid PrintableString"),
203 )
204 }
205 }
206
207 impl<'a> RefToOwned<'a> for PrintableStringRef<'a> {
208 type Owned = PrintableString;
209 fn ref_to_owned(&self) -> Self::Owned {
210 PrintableString {
211 inner: self.inner.ref_to_owned(),
212 }
213 }
214 }
215
216 impl OwnedToRef for PrintableString {
217 type Borrowed<'a> = PrintableStringRef<'a>;
218 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
219 PrintableStringRef {
220 inner: self.inner.owned_to_ref(),
221 }
222 }
223 }
224
225 impl TryFrom<String> for PrintableString {
226 type Error = Error;
227
228 fn try_from(input: String) -> Result<Self> {
229 PrintableStringRef::new(&input)?;
230
231 StrOwned::new(input)
232 .map(|inner| Self { inner })
233 .map_err(|_| Self::TAG.value_error())
234 }
235 }
236}
237
238#[cfg(test)]
239mod tests {
240 use super::PrintableStringRef;
241 use crate::Decode;
242
243 #[test]
244 fn parse_bytes() {
245 let example_bytes = &[
246 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
247 ];
248
249 let printable_string = PrintableStringRef::from_der(example_bytes).unwrap();
250 assert_eq!(printable_string.as_str(), "Test User 1");
251 }
252}