der/asn1/
teletex_string.rs1use crate::{FixedTag, Result, StringRef, Tag, asn1::AnyRef};
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)]
45pub struct TeletexStringRef<'a> {
46 inner: &'a StringRef,
48}
49
50impl<'a> TeletexStringRef<'a> {
51 pub fn new<T>(input: &'a T) -> Result<Self>
56 where
57 T: AsRef<[u8]> + ?Sized,
58 {
59 let input = input.as_ref();
60
61 if input.iter().any(|&c| c > 0x7F) {
63 return Err(Self::TAG.value_error().into());
64 }
65
66 StringRef::from_bytes(input)
67 .map(|inner| Self { inner })
68 .map_err(|_| Self::TAG.value_error().into())
69 }
70
71 #[must_use]
73 pub fn as_str(&self) -> &'a str {
74 self.inner.as_str()
75 }
76}
77
78impl_teletex_string!(TeletexStringRef<'a>, 'a);
79
80impl<'a> Deref for TeletexStringRef<'a> {
81 type Target = StringRef;
82
83 fn deref(&self) -> &Self::Target {
84 self.inner
85 }
86}
87
88impl<'a> From<&TeletexStringRef<'a>> for TeletexStringRef<'a> {
89 fn from(value: &TeletexStringRef<'a>) -> TeletexStringRef<'a> {
90 *value
91 }
92}
93
94impl<'a> From<TeletexStringRef<'a>> for AnyRef<'a> {
95 fn from(teletex_string: TeletexStringRef<'a>) -> AnyRef<'a> {
96 AnyRef::from_tag_and_value(Tag::TeletexString, teletex_string.inner.as_ref())
97 }
98}
99
100#[cfg(feature = "alloc")]
101pub use self::allocation::TeletexString;
102
103#[cfg(feature = "alloc")]
104mod allocation {
105 use super::TeletexStringRef;
106
107 use crate::{
108 BytesRef, Error, FixedTag, Result, StringOwned, Tag,
109 asn1::AnyRef,
110 referenced::{OwnedToRef, RefToOwned},
111 };
112 use alloc::{borrow::ToOwned, string::String};
113 use core::{fmt, ops::Deref};
114
115 #[derive(Clone, Eq, PartialEq, PartialOrd, Ord)]
130 pub struct TeletexString {
131 inner: StringOwned,
133 }
134
135 impl TeletexString {
136 pub fn new<T>(input: &T) -> Result<Self>
141 where
142 T: AsRef<[u8]> + ?Sized,
143 {
144 let input = input.as_ref();
145
146 TeletexStringRef::new(input)?;
147
148 StringOwned::from_bytes(input)
149 .map(|inner| Self { inner })
150 .map_err(|_| Self::TAG.value_error().into())
151 }
152 }
153
154 impl_teletex_string!(TeletexString);
155
156 impl Deref for TeletexString {
157 type Target = StringOwned;
158
159 fn deref(&self) -> &Self::Target {
160 &self.inner
161 }
162 }
163
164 impl<'a> From<TeletexStringRef<'a>> for TeletexString {
165 fn from(value: TeletexStringRef<'a>) -> TeletexString {
166 let inner =
167 StringOwned::from_bytes(value.inner.as_bytes()).expect("Invalid TeletexString");
168 Self { inner }
169 }
170 }
171
172 impl<'a> From<&'a TeletexString> for AnyRef<'a> {
173 fn from(teletex_string: &'a TeletexString) -> AnyRef<'a> {
174 AnyRef::from_tag_and_value(
175 Tag::TeletexString,
176 BytesRef::new(teletex_string.inner.as_bytes()).expect("Invalid TeletexString"),
177 )
178 }
179 }
180
181 impl<'a> From<&'a TeletexString> for TeletexStringRef<'a> {
182 fn from(teletex_string: &'a TeletexString) -> TeletexStringRef<'a> {
183 teletex_string.owned_to_ref()
184 }
185 }
186
187 impl<'a> RefToOwned<'a> for TeletexStringRef<'a> {
188 type Owned = TeletexString;
189 fn ref_to_owned(&self) -> Self::Owned {
190 TeletexString {
191 inner: self.inner.to_owned(),
192 }
193 }
194 }
195
196 impl OwnedToRef for TeletexString {
197 type Borrowed<'a> = TeletexStringRef<'a>;
198 fn owned_to_ref(&self) -> Self::Borrowed<'_> {
199 TeletexStringRef {
200 inner: self.inner.as_ref(),
201 }
202 }
203 }
204
205 impl TryFrom<String> for TeletexString {
206 type Error = Error;
207
208 fn try_from(input: String) -> Result<Self> {
209 TeletexStringRef::new(&input)?;
210
211 StringOwned::new(input)
212 .map(|inner| Self { inner })
213 .map_err(|_| Self::TAG.value_error().into())
214 }
215 }
216}
217
218#[cfg(test)]
219#[allow(clippy::unwrap_used)]
220mod tests {
221 use super::TeletexStringRef;
222 use crate::Decode;
223 use crate::SliceWriter;
224
225 #[test]
226 fn parse_bytes() {
227 let example_bytes = &[
228 0x14, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x20, 0x55, 0x73, 0x65, 0x72, 0x20, 0x31,
229 ];
230
231 let teletex_string = TeletexStringRef::from_der(example_bytes).unwrap();
232 assert_eq!(teletex_string.as_str(), "Test User 1");
233 let mut out = [0_u8; 30];
234 let mut writer = SliceWriter::new(&mut out);
235 writer.encode(&teletex_string).unwrap();
236 let encoded = writer.finish().unwrap();
237 assert_eq!(encoded, example_bytes);
238 }
239}