der/asn1/
teletex_string.rs
1use crate::{asn1::AnyRef, FixedTag, Result, StrRef, Tag};
4use core::{fmt, ops::Deref};
5
6macro_rules! impl_teletex_string {
7 ($type: ty) => {
8 impl_teletex_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::TeletexString;
15 }
16
17 impl<$($li),*> fmt::Debug for $type {
18 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
19 write!(f, "TeletexString({:?})", self.as_str())
20 }
21 }
22 };
23}
24
25#[derive(Copy, Clone, Eq, PartialEq, PartialOrd, Ord)]
42pub struct TeletexStringRef<'a> {
43 inner: StrRef<'a>,
45}
46
47impl<'a> TeletexStringRef<'a> {
48 pub fn new<T>(input: &'a T) -> Result<Self>
50 where
51 T: AsRef<[u8]> + ?Sized,
52 {
53 let input = input.as_ref();
54
55 if input.iter().any(|&c| c > 0x7F) {
57 return Err(Self::TAG.value_error());
58 }
59
60 StrRef::from_bytes(input)
61 .map(|inner| Self { inner })
62 .map_err(|_| Self::TAG.value_error())
63 }
64}
65
66impl_teletex_string!(TeletexStringRef<'a>, 'a);
67
68impl<'a> Deref for TeletexStringRef<'a> {
69 type Target = StrRef<'a>;
70
71 fn deref(&self) -> &Self::Target {
72 &self.inner
73 }
74}
75
76impl<'a> From<&TeletexStringRef<'a>> for TeletexStringRef<'a> {
77 fn from(value: &TeletexStringRef<'a>) -> TeletexStringRef<'a> {
78 *value
79 }
80}
81
82impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
83 fn from(teletex_string: TeletexStringRef<'a>) -> AnyRef<'a> {
84 AnyRef::from_tag_and_value(Tag::TeletexString, teletex_string.inner.into())
85 }
86}
87
88#[cfg(feature = "alloc")]
89pub use self::allocation::TeletexString;
90
91#[cfg(feature = "alloc")]
92mod allocation {
93 use super::TeletexStringRef;
94
95 use crate::{
96 asn1::AnyRef,
97 referenced::{OwnedToRef, RefToOwned},
98 BytesRef, Error, FixedTag, Result, StrOwned, Tag,
99 };
100 use alloc::string::String;
101 use core::{fmt, ops::Deref};
102
103 #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
118 pub struct TeletexString {
119 inner: StrOwned,
121 }
122
123 impl TeletexString {
124 pub fn new<T>(input: &T) -> Result<Self>
126 where
127 T: AsRef<[u8]> + ?Sized,
128 {
129 let input = input.as_ref();
130
131 TeletexStringRef::new(input)?;
132
133 StrOwned::from_bytes(input)
134 .map(|inner| Self { inner })
135 .map_err(|_| Self::TAG.value_error())
136 }
137 }
138
139 impl_teletex_string!(TeletexString);
140
141 impl Deref for TeletexString {
142 type Target = StrOwned;
143
144 fn deref(&self) -> &Self::Target {
145 &self.inner
146 }
147 }
148
149 impl<'a> From<TeletexStringRef<'a>> for TeletexString {
150 fn from(value: TeletexStringRef<'a>) -> TeletexString {
151 let inner =
152 StrOwned::from_bytes(value.inner.as_bytes()).expect("Invalid TeletexString");
153 Self { inner }
154 }
155 }
156
157 impl<'a> From<&'a TeletexString> for AnyRef<'a> {
158 fn from(teletex_string: &'a TeletexString) -> AnyRef<'a> {
159 AnyRef::from_tag_and_value(
160 Tag::TeletexString,
161 BytesRef::new(teletex_string.inner.as_bytes()).expect("Invalid TeletexString"),
162 )
163 }
164 }
165
166 impl<'a> RefToOwned<'a> for TeletexStringRef<'a> {
167 type Owned = TeletexString;
168 fn ref_to_owned(&self) -> Self::Owned {
169 TeletexString {
170 inner: self.inner.ref_to_owned(),
171 }
172 }
173 }
174
175 impl OwnedToRef for TeletexString {
176 type Borrowed<'a> = TeletexStringRef<'a>;
177 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
178 TeletexStringRef {
179 inner: self.inner.owned_to_ref(),
180 }
181 }
182 }
183
184 impl TryFrom<String> for TeletexString {
185 type Error = Error;
186
187 fn try_from(input: String) -> Result<Self> {
188 TeletexStringRef::new(&input)?;
189
190 StrOwned::new(input)
191 .map(|inner| Self { inner })
192 .map_err(|_| Self::TAG.value_error())
193 }
194 }
195}
196
197#[cfg(test)]
198mod tests {
199 use super::TeletexStringRef;
200 use crate::Decode;
201 use crate::SliceWriter;
202
203 #[test]
204 fn parse_bytes() {
205 let example_bytes = &[
206 0x14, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
207 ];
208
209 let teletex_string = TeletexStringRef::from_der(example_bytes).unwrap();
210 assert_eq!(teletex_string.as_str(), "Test User 1");
211 let mut out = [0_u8; 30];
212 let mut writer = SliceWriter::new(&mut out);
213 writer.encode(&teletex_string).unwrap();
214 let encoded = writer.finish().unwrap();
215 assert_eq!(encoded, example_bytes);
216 }
217}