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