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]
194 fn new(value: &str) -> PyResult<Self> {
195 let inner = NumericString::new(value.to_string())
196 .map_err(|e| PyValueError::new_err(format!("Invalid NumericString: {:?}", e)))?;
197 Ok(Self { inner })
198 }
199
200 fn as_str(&self) -> &str {
201 self.inner.as_str()
202 }
203
204 fn __str__(&self) -> &str {
205 self.inner.as_str()
206 }
207
208 fn __repr__(&self) -> String {
209 format!("NumericString('{}')", self.inner.as_str())
210 }
211
212 fn __eq__(&self, other: &Self) -> bool {
213 self.inner == other.inner
214 }
215
216 fn __len__(&self) -> usize {
217 self.inner.as_str().chars().count()
218 }
219
220 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
222 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
223 }
224
225 #[staticmethod]
229 fn from_der(data: &[u8]) -> PyResult<Self> {
230 let inner = NumericString::from_der(data).map_err(SyntaErr)?;
231 Ok(Self { inner })
232 }
233}
234
235#[pyclass(name = "TeletexString")]
237#[derive(Debug, Clone)]
238pub struct PyTeletexString {
239 pub(crate) inner: TeletexString,
240}
241
242#[pymethods]
243impl PyTeletexString {
244 #[new]
246 fn new(data: Vec<u8>) -> Self {
247 Self {
248 inner: TeletexString::new(data),
249 }
250 }
251
252 #[staticmethod]
256 fn from_latin1(value: &str) -> PyResult<Self> {
257 TeletexString::from_latin1(value)
258 .map(|inner| Self { inner })
259 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
260 }
261
262 #[staticmethod]
266 fn from_str(value: &str) -> PyResult<Self> {
267 TeletexString::from_latin1(value)
268 .map(|inner| Self { inner })
269 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
270 }
271
272 fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
274 PyBytes::new(py, self.inner.as_bytes())
275 }
276
277 fn as_str(&self) -> String {
279 self.inner.as_latin1_string()
280 }
281
282 fn __str__(&self) -> String {
283 self.inner.as_latin1_string()
284 }
285
286 fn __repr__(&self) -> String {
287 format!("TeletexString(<{} bytes>)", self.inner.as_bytes().len())
288 }
289
290 fn __len__(&self) -> usize {
291 self.inner.as_bytes().len()
292 }
293
294 fn __eq__(&self, other: &Self) -> bool {
295 self.inner == other.inner
296 }
297
298 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
300 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
301 }
302
303 #[staticmethod]
307 fn from_der(data: &[u8]) -> PyResult<Self> {
308 let inner = TeletexString::from_der(data).map_err(SyntaErr)?;
309 Ok(Self { inner })
310 }
311}
312
313#[pyclass(name = "VisibleString")]
315#[derive(Debug, Clone)]
316pub struct PyVisibleString {
317 pub(crate) inner: VisibleString,
318}
319
320#[pymethods]
321impl PyVisibleString {
322 #[new]
327 fn new(value: &str) -> PyResult<Self> {
328 let inner = VisibleString::new(value.to_string())
329 .map_err(|e| PyValueError::new_err(format!("Invalid VisibleString: {:?}", e)))?;
330 Ok(Self { inner })
331 }
332
333 fn as_str(&self) -> &str {
334 self.inner.as_str()
335 }
336
337 fn __str__(&self) -> &str {
338 self.inner.as_str()
339 }
340
341 fn __repr__(&self) -> String {
342 format!("VisibleString('{}')", self.inner.as_str())
343 }
344
345 fn __eq__(&self, other: &Self) -> bool {
346 self.inner == other.inner
347 }
348
349 fn __len__(&self) -> usize {
350 self.inner.as_str().len()
351 }
352
353 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
355 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
356 }
357
358 #[staticmethod]
362 fn from_der(data: &[u8]) -> PyResult<Self> {
363 let inner = VisibleString::from_der(data).map_err(SyntaErr)?;
364 Ok(Self { inner })
365 }
366}
367
368#[pyclass(name = "GeneralString")]
370#[derive(Debug, Clone)]
371pub struct PyGeneralString {
372 pub(crate) inner: GeneralString,
373}
374
375#[pymethods]
376impl PyGeneralString {
377 #[new]
379 fn new(data: Vec<u8>) -> Self {
380 Self {
381 inner: GeneralString::new(data),
382 }
383 }
384
385 #[staticmethod]
389 fn from_ascii(value: &str) -> PyResult<Self> {
390 GeneralString::from_ascii(value)
391 .map(|inner| Self { inner })
392 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
393 }
394
395 #[staticmethod]
399 fn from_str(value: &str) -> PyResult<Self> {
400 GeneralString::from_ascii(value)
401 .map(|inner| Self { inner })
402 .map_err(|e| PyValueError::new_err(format!("{:?}", e)))
403 }
404
405 fn to_bytes<'py>(&self, py: Python<'py>) -> Bound<'py, PyBytes> {
407 PyBytes::new(py, self.inner.as_bytes())
408 }
409
410 fn as_str(&self) -> String {
412 self.inner.as_latin1_string()
413 }
414
415 fn __str__(&self) -> String {
416 self.inner.as_latin1_string()
417 }
418
419 fn __repr__(&self) -> String {
420 format!("GeneralString(<{} bytes>)", self.inner.as_bytes().len())
421 }
422
423 fn __len__(&self) -> usize {
424 self.inner.as_bytes().len()
425 }
426
427 fn __eq__(&self, other: &Self) -> bool {
428 self.inner == other.inner
429 }
430
431 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
433 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
434 }
435
436 #[staticmethod]
440 fn from_der(data: &[u8]) -> PyResult<Self> {
441 let inner = GeneralString::from_der(data).map_err(SyntaErr)?;
442 Ok(Self { inner })
443 }
444}
445
446#[pyclass(name = "UniversalString")]
448#[derive(Debug, Clone)]
449pub struct PyUniversalString {
450 pub(crate) inner: UniversalString,
451}
452
453#[pymethods]
454impl PyUniversalString {
455 #[new]
457 fn new(value: &str) -> Self {
458 Self {
459 inner: UniversalString::new(value.to_string()),
460 }
461 }
462
463 #[staticmethod]
465 fn from_bytes(data: &[u8]) -> PyResult<Self> {
466 let inner = UniversalString::from_ucs4_be(data)
467 .map_err(|e| PyValueError::new_err(format!("Invalid UniversalString: {:?}", e)))?;
468 Ok(Self { inner })
469 }
470
471 fn as_str(&self) -> &str {
472 self.inner.as_str()
473 }
474
475 fn __str__(&self) -> &str {
476 self.inner.as_str()
477 }
478
479 fn __repr__(&self) -> String {
480 format!("UniversalString('{}')", self.inner.as_str())
481 }
482
483 fn __eq__(&self, other: &Self) -> bool {
484 self.inner == other.inner
485 }
486
487 fn __len__(&self) -> usize {
488 self.inner.as_str().chars().count()
489 }
490
491 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
493 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
494 }
495
496 #[staticmethod]
500 fn from_der(data: &[u8]) -> PyResult<Self> {
501 let inner = UniversalString::from_der(data).map_err(SyntaErr)?;
502 Ok(Self { inner })
503 }
504}
505
506#[pyclass(name = "BmpString")]
508#[derive(Debug, Clone)]
509pub struct PyBmpString {
510 pub(crate) inner: BmpString,
511}
512
513#[pymethods]
514impl PyBmpString {
515 #[new]
517 fn new(value: &str) -> PyResult<Self> {
518 let inner = BmpString::new(value.to_string())
519 .map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
520 Ok(Self { inner })
521 }
522
523 #[staticmethod]
525 fn from_bytes(data: &[u8]) -> PyResult<Self> {
526 let inner = BmpString::from_ucs2_be(data)
527 .map_err(|e| PyValueError::new_err(format!("Invalid BMPString: {:?}", e)))?;
528 Ok(Self { inner })
529 }
530
531 fn as_str(&self) -> &str {
532 self.inner.as_str()
533 }
534
535 fn __str__(&self) -> &str {
536 self.inner.as_str()
537 }
538
539 fn __repr__(&self) -> String {
540 format!("BmpString('{}')", self.inner.as_str())
541 }
542
543 fn __eq__(&self, other: &Self) -> bool {
544 self.inner == other.inner
545 }
546
547 fn __len__(&self) -> usize {
548 self.inner.as_str().chars().count()
549 }
550
551 fn to_der<'py>(&self, py: Python<'py>) -> PyResult<Bound<'py, PyBytes>> {
553 Ok(PyBytes::new(py, &self.inner.to_der().map_err(SyntaErr)?))
554 }
555
556 #[staticmethod]
560 fn from_der(data: &[u8]) -> PyResult<Self> {
561 let inner = BmpString::from_der(data).map_err(SyntaErr)?;
562 Ok(Self { inner })
563 }
564}