1use pyo3::exceptions::PyValueError;
5use pyo3::prelude::*;
6use pyo3::types::PyBytes;
7
8use synta::{
9 BmpString, FromDer, GeneralString, IA5String, NumericString, PrintableString, TeletexString,
10 ToDer, UniversalString, Utf8String, VisibleString,
11};
12
13use crate::error::SyntaErr;
14
15#[pyclass(name = "Utf8String")]
17#[derive(Debug, Clone)]
18pub struct PyUtf8String {
19 pub(crate) inner: Utf8String,
20}
21
22#[pymethods]
23impl PyUtf8String {
24 #[new]
26 fn new(value: &str) -> Self {
27 Self {
28 inner: Utf8String::new(value.to_string()),
29 }
30 }
31
32 fn as_str(&self) -> &str {
34 self.inner.as_str()
35 }
36
37 fn __str__(&self) -> &str {
38 self.inner.as_str()
39 }
40
41 fn __repr__(&self) -> String {
42 format!("Utf8String('{}')", self.inner.as_str())
43 }
44
45 fn __eq__(&self, other: &Self) -> bool {
46 self.inner == other.inner
47 }
48
49 fn __len__(&self) -> usize {
50 self.inner.as_str().chars().count()
51 }
52
53 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
55 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
56 }
57
58 #[staticmethod]
62 fn from_der(data: &[u8]) -> PyResult<Self> {
63 let inner = Utf8String::from_der(data).map_err(SyntaErr)?;
64 Ok(Self { inner })
65 }
66}
67
68#[pyclass(name = "PrintableString")]
73#[derive(Debug, Clone)]
74pub struct PyPrintableString {
75 pub(crate) inner: PrintableString,
76}
77
78#[pymethods]
79impl PyPrintableString {
80 #[new]
84 fn new(value: &str) -> PyResult<Self> {
85 let inner = PrintableString::new(value.to_string())
86 .map_err(|e| PyValueError::new_err(format!("Invalid PrintableString: {:?}", e)))?;
87 Ok(Self { inner })
88 }
89
90 fn as_str(&self) -> &str {
92 self.inner.as_str()
93 }
94
95 fn __str__(&self) -> &str {
96 self.inner.as_str()
97 }
98
99 fn __repr__(&self) -> String {
100 format!("PrintableString('{}')", self.inner.as_str())
101 }
102
103 fn __eq__(&self, other: &Self) -> bool {
104 self.inner == other.inner
105 }
106
107 fn __len__(&self) -> usize {
108 self.inner.as_str().chars().count()
109 }
110
111 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
113 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
114 }
115
116 #[staticmethod]
120 fn from_der(data: &[u8]) -> PyResult<Self> {
121 let inner = PrintableString::from_der(data).map_err(SyntaErr)?;
122 Ok(Self { inner })
123 }
124}
125
126#[pyclass(name = "IA5String")]
128#[derive(Debug, Clone)]
129pub struct PyIA5String {
130 pub(crate) inner: IA5String,
131}
132
133#[pymethods]
134impl PyIA5String {
135 #[new]
139 fn new(value: &str) -> PyResult<Self> {
140 let inner = IA5String::new(value.to_string())
141 .map_err(|e| PyValueError::new_err(format!("Invalid IA5String: {:?}", e)))?;
142 Ok(Self { inner })
143 }
144
145 fn as_str(&self) -> &str {
147 self.inner.as_str()
148 }
149
150 fn __str__(&self) -> &str {
151 self.inner.as_str()
152 }
153
154 fn __repr__(&self) -> String {
155 format!("IA5String('{}')", self.inner.as_str())
156 }
157
158 fn __eq__(&self, other: &Self) -> bool {
159 self.inner == other.inner
160 }
161
162 fn __len__(&self) -> usize {
163 self.inner.as_str().chars().count()
164 }
165
166 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
168 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
169 }
170
171 #[staticmethod]
175 fn from_der(data: &[u8]) -> PyResult<Self> {
176 let inner = IA5String::from_der(data).map_err(SyntaErr)?;
177 Ok(Self { inner })
178 }
179}
180
181#[pyclass(name = "NumericString")]
183#[derive(Debug, Clone)]
184pub struct PyNumericString {
185 pub(crate) inner: NumericString,
186}
187
188#[pymethods]
189impl PyNumericString {
190 #[new]
191 fn new(value: &str) -> PyResult<Self> {
192 let inner = NumericString::new(value.to_string())
193 .map_err(|e| PyValueError::new_err(format!("Invalid NumericString: {:?}", e)))?;
194 Ok(Self { inner })
195 }
196
197 fn as_str(&self) -> &str {
198 self.inner.as_str()
199 }
200
201 fn __str__(&self) -> &str {
202 self.inner.as_str()
203 }
204
205 fn __repr__(&self) -> String {
206 format!("NumericString('{}')", self.inner.as_str())
207 }
208
209 fn __eq__(&self, other: &Self) -> bool {
210 self.inner == other.inner
211 }
212
213 fn __len__(&self) -> usize {
214 self.inner.as_str().chars().count()
215 }
216
217 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
219 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
220 }
221
222 #[staticmethod]
226 fn from_der(data: &[u8]) -> PyResult<Self> {
227 let inner = NumericString::from_der(data).map_err(SyntaErr)?;
228 Ok(Self { inner })
229 }
230}
231
232#[pyclass(name = "TeletexString")]
234#[derive(Debug, Clone)]
235pub struct PyTeletexString {
236 pub(crate) inner: TeletexString,
237}
238
239#[pymethods]
240impl PyTeletexString {
241 #[new]
243 fn new(data: Vec<u8>) -> Self {
244 Self {
245 inner: TeletexString::new(data),
246 }
247 }
248
249 #[staticmethod]
253 fn from_latin1(value: &str) -> PyResult<Self> {
254 TeletexString::from_latin1(value)
255 .map(|inner| Self { inner })
256 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
257 }
258
259 #[staticmethod]
263 fn from_str(value: &str) -> PyResult<Self> {
264 TeletexString::from_latin1(value)
265 .map(|inner| Self { inner })
266 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
267 }
268
269 fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
271 PyBytes::new(py, self.inner.as_bytes())
272 }
273
274 fn as_str(&self) -> String {
276 self.inner.as_latin1_string()
277 }
278
279 fn __str__(&self) -> String {
280 self.inner.as_latin1_string()
281 }
282
283 fn __repr__(&self) -> String {
284 format!("TeletexString(<{} bytes>)", self.inner.as_bytes().len())
285 }
286
287 fn __len__(&self) -> usize {
288 self.inner.as_bytes().len()
289 }
290
291 fn __eq__(&self, other: &Self) -> bool {
292 self.inner == other.inner
293 }
294
295 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
297 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
298 }
299
300 #[staticmethod]
304 fn from_der(data: &[u8]) -> PyResult<Self> {
305 let inner = TeletexString::from_der(data).map_err(SyntaErr)?;
306 Ok(Self { inner })
307 }
308}
309
310#[pyclass(name = "VisibleString")]
312#[derive(Debug, Clone)]
313pub struct PyVisibleString {
314 pub(crate) inner: VisibleString,
315}
316
317#[pymethods]
318impl PyVisibleString {
319 #[new]
320 fn new(value: &str) -> PyResult<Self> {
321 let inner = VisibleString::new(value.to_string())
322 .map_err(|e| PyValueError::new_err(format!("Invalid VisibleString: {:?}", e)))?;
323 Ok(Self { inner })
324 }
325
326 fn as_str(&self) -> &str {
327 self.inner.as_str()
328 }
329
330 fn __str__(&self) -> &str {
331 self.inner.as_str()
332 }
333
334 fn __repr__(&self) -> String {
335 format!("VisibleString('{}')", self.inner.as_str())
336 }
337
338 fn __eq__(&self, other: &Self) -> bool {
339 self.inner == other.inner
340 }
341
342 fn __len__(&self) -> usize {
343 self.inner.as_str().len()
344 }
345
346 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
348 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
349 }
350
351 #[staticmethod]
355 fn from_der(data: &[u8]) -> PyResult<Self> {
356 let inner = VisibleString::from_der(data).map_err(SyntaErr)?;
357 Ok(Self { inner })
358 }
359}
360
361#[pyclass(name = "GeneralString")]
363#[derive(Debug, Clone)]
364pub struct PyGeneralString {
365 pub(crate) inner: GeneralString,
366}
367
368#[pymethods]
369impl PyGeneralString {
370 #[new]
372 fn new(data: Vec<u8>) -> Self {
373 Self {
374 inner: GeneralString::new(data),
375 }
376 }
377
378 #[staticmethod]
382 fn from_ascii(value: &str) -> PyResult<Self> {
383 GeneralString::from_ascii(value)
384 .map(|inner| Self { inner })
385 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
386 }
387
388 #[staticmethod]
392 fn from_str(value: &str) -> PyResult<Self> {
393 GeneralString::from_ascii(value)
394 .map(|inner| Self { inner })
395 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
396 }
397
398 fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
400 PyBytes::new(py, self.inner.as_bytes())
401 }
402
403 fn as_str(&self) -> String {
405 self.inner.as_latin1_string()
406 }
407
408 fn __str__(&self) -> String {
409 self.inner.as_latin1_string()
410 }
411
412 fn __repr__(&self) -> String {
413 format!("GeneralString(<{} bytes>)", self.inner.as_bytes().len())
414 }
415
416 fn __len__(&self) -> usize {
417 self.inner.as_bytes().len()
418 }
419
420 fn __eq__(&self, other: &Self) -> bool {
421 self.inner == other.inner
422 }
423
424 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
426 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
427 }
428
429 #[staticmethod]
433 fn from_der(data: &[u8]) -> PyResult<Self> {
434 let inner = GeneralString::from_der(data).map_err(SyntaErr)?;
435 Ok(Self { inner })
436 }
437}
438
439#[pyclass(name = "UniversalString")]
441#[derive(Debug, Clone)]
442pub struct PyUniversalString {
443 pub(crate) inner: UniversalString,
444}
445
446#[pymethods]
447impl PyUniversalString {
448 #[new]
450 fn new(value: &str) -> Self {
451 Self {
452 inner: UniversalString::new(value.to_string()),
453 }
454 }
455
456 #[staticmethod]
458 fn from_bytes(data: &[u8]) -> PyResult<Self> {
459 let inner = UniversalString::from_ucs4_be(data)
460 .map_err(|e| PyValueError::new_err(format!("Invalid UniversalString: {:?}", e)))?;
461 Ok(Self { inner })
462 }
463
464 fn as_str(&self) -> &str {
465 self.inner.as_str()
466 }
467
468 fn __str__(&self) -> &str {
469 self.inner.as_str()
470 }
471
472 fn __repr__(&self) -> String {
473 format!("UniversalString('{}')", self.inner.as_str())
474 }
475
476 fn __eq__(&self, other: &Self) -> bool {
477 self.inner == other.inner
478 }
479
480 fn __len__(&self) -> usize {
481 self.inner.as_str().chars().count()
482 }
483
484 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
486 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
487 }
488
489 #[staticmethod]
493 fn from_der(data: &[u8]) -> PyResult<Self> {
494 let inner = UniversalString::from_der(data).map_err(SyntaErr)?;
495 Ok(Self { inner })
496 }
497}
498
499#[pyclass(name = "BmpString")]
501#[derive(Debug, Clone)]
502pub struct PyBmpString {
503 pub(crate) inner: BmpString,
504}
505
506#[pymethods]
507impl PyBmpString {
508 #[new]
510 fn new(value: &str) -> PyResult<Self> {
511 let inner = BmpString::new(value.to_string())
512 .map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
513 Ok(Self { inner })
514 }
515
516 #[staticmethod]
518 fn from_bytes(data: &[u8]) -> PyResult<Self> {
519 let inner = BmpString::from_ucs2_be(data)
520 .map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
521 Ok(Self { inner })
522 }
523
524 fn as_str(&self) -> &str {
525 self.inner.as_str()
526 }
527
528 fn __str__(&self) -> &str {
529 self.inner.as_str()
530 }
531
532 fn __repr__(&self) -> String {
533 format!("BmpString('{}')", self.inner.as_str())
534 }
535
536 fn __eq__(&self, other: &Self) -> bool {
537 self.inner == other.inner
538 }
539
540 fn __len__(&self) -> usize {
541 self.inner.as_str().chars().count()
542 }
543
544 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
546 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
547 }
548
549 #[staticmethod]
553 fn from_der(data: &[u8]) -> PyResult<Self> {
554 let inner = BmpString::from_der(data).map_err(SyntaErr)?;
555 Ok(Self { inner })
556 }
557}