asn1_rs/asn1_types/
strings.rs1mod bmpstring;
2mod generalstring;
3mod graphicstring;
4mod ia5string;
5mod numericstring;
6mod printablestring;
7mod str;
8mod string;
9mod teletexstring;
10mod universalstring;
11mod utf8string;
12mod videotexstring;
13mod visiblestring;
14
15pub use bmpstring::*;
16pub use generalstring::*;
17pub use graphicstring::*;
18pub use ia5string::*;
19pub use numericstring::*;
20pub use printablestring::*;
21
22pub use teletexstring::*;
23pub use universalstring::*;
24pub use utf8string::*;
25pub use videotexstring::*;
26pub use visiblestring::*;
27
28pub trait TestValidCharset {
45 fn test_valid_charset(i: &[u8]) -> crate::Result<()>;
47}
48
49#[doc(hidden)]
50#[macro_export]
51macro_rules! asn1_string {
52 (IMPL $name:ident, $sname:expr) => {
53 #[doc="ASN.1 restricted character string type (`"]
54 #[doc = $sname]
55 #[doc = "`)"]
56 #[derive(Debug, PartialEq, Eq)]
57 pub struct $name<'a> {
58 pub(crate) data: alloc::borrow::Cow<'a, str>,
59 }
60
61 impl<'a> $name<'a> {
62 pub const fn new(s: &'a str) -> Self {
63 $name {
64 data: alloc::borrow::Cow::Borrowed(s),
65 }
66 }
67
68 pub fn string(&self) -> String {
69 use alloc::string::ToString;
70 self.data.to_string()
71 }
72 }
73
74 impl<'a> AsRef<str> for $name<'a> {
75 fn as_ref(&self) -> &str {
76 &self.data
77 }
78 }
79
80 impl<'a> From<&'a str> for $name<'a> {
81 fn from(s: &'a str) -> Self {
82 Self::new(s)
83 }
84 }
85
86 impl From<String> for $name<'_> {
87 fn from(s: String) -> Self {
88 Self {
89 data: alloc::borrow::Cow::Owned(s),
90 }
91 }
92 }
93
94 impl<'a> core::convert::TryFrom<$crate::Any<'a>> for $name<'a> {
95 type Error = $crate::Error;
96
97 fn try_from(any: $crate::Any<'a>) -> $crate::Result<$name<'a>> {
98 use core::convert::TryFrom;
99 TryFrom::try_from(&any)
100 }
101 }
102
103 impl<'a, 'b> core::convert::TryFrom<&'b $crate::Any<'a>> for $name<'a> {
104 type Error = $crate::Error;
105
106 fn try_from(any: &'b $crate::Any<'a>) -> $crate::Result<$name<'a>> {
107 use $crate::traits::Tagged;
108 use alloc::borrow::Cow;
109 any.tag().assert_eq(Self::TAG)?;
110 <$name>::test_valid_charset(any.data)?;
111
112 let s = alloc::str::from_utf8(any.data)?;
113 let data = Cow::Borrowed(s);
114 Ok($name { data })
115 }
116 }
117
118 impl<'a> $crate::CheckDerConstraints for $name<'a> {
119 fn check_constraints(any: &$crate::Any) -> $crate::Result<()> {
120 any.header.assert_primitive()?;
121 Ok(())
122 }
123 }
124
125 impl $crate::DerAutoDerive for $name<'_> {}
126
127 impl<'a> $crate::Tagged for $name<'a> {
128 const TAG: $crate::Tag = $crate::Tag::$name;
129 }
130
131 #[cfg(feature = "std")]
132 impl $crate::ToDer for $name<'_> {
133 fn to_der_len(&self) -> Result<usize> {
134 let sz = self.data.as_bytes().len();
135 if sz < 127 {
136 Ok(2 + sz)
138 } else {
139 let n = $crate::Length::Definite(sz).to_der_len()?;
141 Ok(1 + n + sz)
142 }
143 }
144
145 fn write_der_header(
146 &self,
147 writer: &mut dyn std::io::Write,
148 ) -> $crate::SerializeResult<usize> {
149 use $crate::Tagged;
150 let header = $crate::Header::new(
151 $crate::Class::Universal,
152 false,
153 Self::TAG,
154 $crate::Length::Definite(self.data.len()),
155 );
156 header.write_der_header(writer).map_err(Into::into)
157 }
158
159 fn write_der_content(
160 &self,
161 writer: &mut dyn std::io::Write,
162 ) -> $crate::SerializeResult<usize> {
163 writer.write(self.data.as_bytes()).map_err(Into::into)
164 }
165 }
166 };
167 ($name:ident) => {
168 asn1_string!(IMPL $name, stringify!($name));
169 };
170}