der/asn1/
printable_string.rs
1use crate::{
4 asn1::Any, ByteSlice, DecodeValue, Decoder, EncodeValue, Encoder, Error, FixedTag, Length,
5 OrdIsValueOrd, Result, StrSlice, Tag,
6};
7use core::{fmt, str};
8
9#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
36pub struct PrintableString<'a> {
37 inner: StrSlice<'a>,
39}
40
41impl<'a> PrintableString<'a> {
42 pub fn new<T>(input: &'a T) -> Result<Self>
44 where
45 T: AsRef<[u8]> + ?Sized,
46 {
47 let input = input.as_ref();
48
49 for &c in input.iter() {
51 match c {
52 b'A'..=b'Z'
53 | b'a'..=b'z'
54 | b'0'..=b'9'
55 | b' '
56 | b'\''
57 | b'('
58 | b')'
59 | b'+'
60 | b','
61 | b'-'
62 | b'.'
63 | b'/'
64 | b':'
65 | b'='
66 | b'?' => (),
67 _ => return Err(Self::TAG.value_error()),
68 }
69 }
70
71 StrSlice::from_bytes(input)
72 .map(|inner| Self { inner })
73 .map_err(|_| Self::TAG.value_error())
74 }
75
76 pub fn as_str(&self) -> &'a str {
78 self.inner.as_str()
79 }
80
81 pub fn as_bytes(&self) -> &'a [u8] {
83 self.inner.as_bytes()
84 }
85
86 pub fn len(&self) -> Length {
88 self.inner.len()
89 }
90
91 pub fn is_empty(&self) -> bool {
93 self.inner.is_empty()
94 }
95}
96
97impl AsRef<str> for PrintableString<'_> {
98 fn as_ref(&self) -> &str {
99 self.as_str()
100 }
101}
102
103impl AsRef<[u8]> for PrintableString<'_> {
104 fn as_ref(&self) -> &[u8] {
105 self.as_bytes()
106 }
107}
108
109impl<'a> DecodeValue<'a> for PrintableString<'a> {
110 fn decode_value(decoder: &mut Decoder<'a>, length: Length) -> Result<Self> {
111 Self::new(ByteSlice::decode_value(decoder, length)?.as_bytes())
112 }
113}
114
115impl<'a> EncodeValue for PrintableString<'a> {
116 fn value_len(&self) -> Result<Length> {
117 self.inner.value_len()
118 }
119
120 fn encode_value(&self, encoder: &mut Encoder<'_>) -> Result<()> {
121 self.inner.encode_value(encoder)
122 }
123}
124
125impl FixedTag for PrintableString<'_> {
126 const TAG: Tag = Tag::PrintableString;
127}
128
129impl OrdIsValueOrd for PrintableString<'_> {}
130
131impl<'a> From<&PrintableString<'a>> for PrintableString<'a> {
132 fn from(value: &PrintableString<'a>) -> PrintableString<'a> {
133 *value
134 }
135}
136
137impl<'a> TryFrom<Any<'a>> for PrintableString<'a> {
138 type Error = Error;
139
140 fn try_from(any: Any<'a>) -> Result<PrintableString<'a>> {
141 any.decode_into()
142 }
143}
144
145impl<'a> From<PrintableString<'a>> for Any<'a> {
146 fn from(printable_string: PrintableString<'a>) -> Any<'a> {
147 Any::from_tag_and_value(Tag::PrintableString, printable_string.inner.into())
148 }
149}
150
151impl<'a> From<PrintableString<'a>> for &'a [u8] {
152 fn from(printable_string: PrintableString<'a>) -> &'a [u8] {
153 printable_string.as_bytes()
154 }
155}
156
157impl<'a> fmt::Display for PrintableString<'a> {
158 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
159 f.write_str(self.as_str())
160 }
161}
162
163impl<'a> fmt::Debug for PrintableString<'a> {
164 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
165 write!(f, "PrintableString({:?})", self.as_str())
166 }
167}
168
169#[cfg(test)]
170mod tests {
171 use super::PrintableString;
172 use crate::Decodable;
173
174 #[test]
175 fn parse_bytes() {
176 let example_bytes = &[
177 0x13, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
178 ];
179
180 let printable_string = PrintableString::from_der(example_bytes).unwrap();
181 assert_eq!(printable_string.as_str(), "Test User 1");
182 }
183}