1use pyo3::exceptions::PyValueError;
5use pyo3::prelude::*;
6use pyo3::types::PyBytes;
7
8use synta::{
9 BmpString, GeneralString, IA5String, NumericString, PrintableString, TeletexString,
10 UniversalString, Utf8String, VisibleString,
11};
12
13#[pyclass(name = "Utf8String")]
15#[derive(Debug, Clone)]
16pub struct PyUtf8String {
17 pub(crate) inner: Utf8String,
18}
19
20#[pymethods]
21impl PyUtf8String {
22 #[new]
24 fn new(value: &str) -> Self {
25 Self {
26 inner: Utf8String::new(value.to_string()),
27 }
28 }
29
30 fn as_str(&self) -> &str {
32 self.inner.as_str()
33 }
34
35 fn __str__(&self) -> &str {
36 self.inner.as_str()
37 }
38
39 fn __repr__(&self) -> String {
40 format!("Utf8String('{}')", self.inner.as_str())
41 }
42
43 fn __eq__(&self, other: &Self) -> bool {
44 self.inner == other.inner
45 }
46
47 fn __len__(&self) -> usize {
48 self.inner.as_str().chars().count()
49 }
50}
51
52#[pyclass(name = "PrintableString")]
57#[derive(Debug, Clone)]
58pub struct PyPrintableString {
59 pub(crate) inner: PrintableString,
60}
61
62#[pymethods]
63impl PyPrintableString {
64 #[new]
68 fn new(value: &str) -> PyResult<Self> {
69 let inner = PrintableString::new(value.to_string())
70 .map_err(|e| PyValueError::new_err(format!("Invalid PrintableString: {:?}", e)))?;
71 Ok(Self { inner })
72 }
73
74 fn as_str(&self) -> &str {
76 self.inner.as_str()
77 }
78
79 fn __str__(&self) -> &str {
80 self.inner.as_str()
81 }
82
83 fn __repr__(&self) -> String {
84 format!("PrintableString('{}')", self.inner.as_str())
85 }
86
87 fn __eq__(&self, other: &Self) -> bool {
88 self.inner == other.inner
89 }
90
91 fn __len__(&self) -> usize {
92 self.inner.as_str().chars().count()
93 }
94}
95
96#[pyclass(name = "IA5String")]
98#[derive(Debug, Clone)]
99pub struct PyIA5String {
100 pub(crate) inner: IA5String,
101}
102
103#[pymethods]
104impl PyIA5String {
105 #[new]
109 fn new(value: &str) -> PyResult<Self> {
110 let inner = IA5String::new(value.to_string())
111 .map_err(|e| PyValueError::new_err(format!("Invalid IA5String: {:?}", e)))?;
112 Ok(Self { inner })
113 }
114
115 fn as_str(&self) -> &str {
117 self.inner.as_str()
118 }
119
120 fn __str__(&self) -> &str {
121 self.inner.as_str()
122 }
123
124 fn __repr__(&self) -> String {
125 format!("IA5String('{}')", self.inner.as_str())
126 }
127
128 fn __eq__(&self, other: &Self) -> bool {
129 self.inner == other.inner
130 }
131
132 fn __len__(&self) -> usize {
133 self.inner.as_str().chars().count()
134 }
135}
136
137#[pyclass(name = "NumericString")]
139#[derive(Debug, Clone)]
140pub struct PyNumericString {
141 pub(crate) inner: NumericString,
142}
143
144#[pymethods]
145impl PyNumericString {
146 #[new]
147 fn new(value: &str) -> PyResult<Self> {
148 let inner = NumericString::new(value.to_string())
149 .map_err(|e| PyValueError::new_err(format!("Invalid NumericString: {:?}", e)))?;
150 Ok(Self { inner })
151 }
152
153 fn as_str(&self) -> &str {
154 self.inner.as_str()
155 }
156
157 fn __str__(&self) -> &str {
158 self.inner.as_str()
159 }
160
161 fn __repr__(&self) -> String {
162 format!("NumericString('{}')", self.inner.as_str())
163 }
164
165 fn __eq__(&self, other: &Self) -> bool {
166 self.inner == other.inner
167 }
168
169 fn __len__(&self) -> usize {
170 self.inner.as_str().chars().count()
171 }
172}
173
174#[pyclass(name = "TeletexString")]
176#[derive(Debug, Clone)]
177pub struct PyTeletexString {
178 pub(crate) inner: TeletexString,
179}
180
181#[pymethods]
182impl PyTeletexString {
183 #[new]
185 fn new(data: Vec<u8>) -> Self {
186 Self {
187 inner: TeletexString::new(data),
188 }
189 }
190
191 #[staticmethod]
195 fn from_latin1(value: &str) -> PyResult<Self> {
196 TeletexString::from_latin1(value)
197 .map(|inner| Self { inner })
198 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
199 }
200
201 #[staticmethod]
205 fn from_str(value: &str) -> PyResult<Self> {
206 TeletexString::from_latin1(value)
207 .map(|inner| Self { inner })
208 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
209 }
210
211 fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
213 PyBytes::new(py, self.inner.as_bytes())
214 }
215
216 fn as_str(&self) -> String {
218 self.inner.as_latin1_string()
219 }
220
221 fn __str__(&self) -> String {
222 self.inner.as_latin1_string()
223 }
224
225 fn __repr__(&self) -> String {
226 format!("TeletexString(<{} bytes>)", self.inner.as_bytes().len())
227 }
228
229 fn __len__(&self) -> usize {
230 self.inner.as_bytes().len()
231 }
232
233 fn __eq__(&self, other: &Self) -> bool {
234 self.inner == other.inner
235 }
236}
237
238#[pyclass(name = "VisibleString")]
240#[derive(Debug, Clone)]
241pub struct PyVisibleString {
242 pub(crate) inner: VisibleString,
243}
244
245#[pymethods]
246impl PyVisibleString {
247 #[new]
248 fn new(value: &str) -> PyResult<Self> {
249 let inner = VisibleString::new(value.to_string())
250 .map_err(|e| PyValueError::new_err(format!("Invalid VisibleString: {:?}", e)))?;
251 Ok(Self { inner })
252 }
253
254 fn as_str(&self) -> &str {
255 self.inner.as_str()
256 }
257
258 fn __str__(&self) -> &str {
259 self.inner.as_str()
260 }
261
262 fn __repr__(&self) -> String {
263 format!("VisibleString('{}')", self.inner.as_str())
264 }
265
266 fn __eq__(&self, other: &Self) -> bool {
267 self.inner == other.inner
268 }
269
270 fn __len__(&self) -> usize {
271 self.inner.as_str().len()
272 }
273}
274
275#[pyclass(name = "GeneralString")]
277#[derive(Debug, Clone)]
278pub struct PyGeneralString {
279 pub(crate) inner: GeneralString,
280}
281
282#[pymethods]
283impl PyGeneralString {
284 #[new]
286 fn new(data: Vec<u8>) -> Self {
287 Self {
288 inner: GeneralString::new(data),
289 }
290 }
291
292 #[staticmethod]
296 fn from_ascii(value: &str) -> PyResult<Self> {
297 GeneralString::from_ascii(value)
298 .map(|inner| Self { inner })
299 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
300 }
301
302 #[staticmethod]
306 fn from_str(value: &str) -> PyResult<Self> {
307 GeneralString::from_ascii(value)
308 .map(|inner| Self { inner })
309 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
310 }
311
312 fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
314 PyBytes::new(py, self.inner.as_bytes())
315 }
316
317 fn as_str(&self) -> String {
319 self.inner.as_latin1_string()
320 }
321
322 fn __str__(&self) -> String {
323 self.inner.as_latin1_string()
324 }
325
326 fn __repr__(&self) -> String {
327 format!("GeneralString(<{} bytes>)", self.inner.as_bytes().len())
328 }
329
330 fn __len__(&self) -> usize {
331 self.inner.as_bytes().len()
332 }
333
334 fn __eq__(&self, other: &Self) -> bool {
335 self.inner == other.inner
336 }
337}
338
339#[pyclass(name = "UniversalString")]
341#[derive(Debug, Clone)]
342pub struct PyUniversalString {
343 pub(crate) inner: UniversalString,
344}
345
346#[pymethods]
347impl PyUniversalString {
348 #[new]
350 fn new(value: &str) -> Self {
351 Self {
352 inner: UniversalString::new(value.to_string()),
353 }
354 }
355
356 #[staticmethod]
358 fn from_bytes(data: &[u8]) -> PyResult<Self> {
359 let inner = UniversalString::from_ucs4_be(data)
360 .map_err(|e| PyValueError::new_err(format!("Invalid UniversalString: {:?}", e)))?;
361 Ok(Self { inner })
362 }
363
364 fn as_str(&self) -> &str {
365 self.inner.as_str()
366 }
367
368 fn __str__(&self) -> &str {
369 self.inner.as_str()
370 }
371
372 fn __repr__(&self) -> String {
373 format!("UniversalString('{}')", self.inner.as_str())
374 }
375
376 fn __eq__(&self, other: &Self) -> bool {
377 self.inner == other.inner
378 }
379
380 fn __len__(&self) -> usize {
381 self.inner.as_str().chars().count()
382 }
383}
384
385#[pyclass(name = "BmpString")]
387#[derive(Debug, Clone)]
388pub struct PyBmpString {
389 pub(crate) inner: BmpString,
390}
391
392#[pymethods]
393impl PyBmpString {
394 #[new]
396 fn new(value: &str) -> PyResult<Self> {
397 let inner = BmpString::new(value.to_string())
398 .map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
399 Ok(Self { inner })
400 }
401
402 #[staticmethod]
404 fn from_bytes(data: &[u8]) -> PyResult<Self> {
405 let inner = BmpString::from_ucs2_be(data)
406 .map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
407 Ok(Self { inner })
408 }
409
410 fn as_str(&self) -> &str {
411 self.inner.as_str()
412 }
413
414 fn __str__(&self) -> &str {
415 self.inner.as_str()
416 }
417
418 fn __repr__(&self) -> String {
419 format!("BmpString('{}')", self.inner.as_str())
420 }
421
422 fn __eq__(&self, other: &Self) -> bool {
423 self.inner == other.inner
424 }
425
426 fn __len__(&self) -> usize {
427 self.inner.as_str().chars().count()
428 }
429}