1use std::str::FromStr;
2
3use pyo3::{prelude::*, type_object::PyTypeInfo, types::PyType, Bound};
4
5use crate::{
6 enums::{Compression, Encoding, SType, Schema, SecurityUpdateAction, UserDefinedInstrument},
7 Action, ErrorCode, InstrumentClass, MatchAlgorithm, RType, Side, StatType, StatusAction,
8 StatusReason, SystemCode, TradingEvent, TriState, VersionUpgradePolicy,
9};
10
11use super::{to_py_err, EnumIterator, PyFieldDesc};
12
13#[pymethods]
14impl Side {
15 #[new]
16 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
17 let Ok(i) = value.extract::<u8>() else {
18 let t = Self::type_object(py);
19 let c = value.extract::<char>().map_err(to_py_err)?;
20 return Self::py_from_str(&t, c);
21 };
22 Self::try_from(i).map_err(to_py_err)
23 }
24
25 fn __hash__(&self) -> isize {
26 *self as isize
27 }
28
29 fn __str__(&self) -> String {
30 format!("{}", *self as u8 as char)
31 }
32
33 fn __repr__(&self) -> String {
34 format!("<Side.{}: '{}'>", self.name(), self.value())
35 }
36
37 #[getter]
38 fn name(&self) -> String {
39 self.as_ref().to_ascii_uppercase()
40 }
41
42 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
43 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
44 return false;
45 };
46 self.eq(&other_enum)
47 }
48
49 #[getter]
50 fn value(&self) -> String {
51 self.__str__()
52 }
53
54 #[classmethod]
55 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
56 EnumIterator::new::<Self>(py)
57 }
58
59 #[classmethod]
60 #[pyo3(name = "from_str")]
61 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
62 Self::try_from(value as u8).map_err(to_py_err)
63 }
64}
65
66#[pymethods]
67impl Action {
68 #[new]
69 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
70 let Ok(i) = value.extract::<u8>() else {
71 let t = Self::type_object(py);
72 let c = value.extract::<char>().map_err(to_py_err)?;
73 return Self::py_from_str(&t, c);
74 };
75 Self::try_from(i).map_err(to_py_err)
76 }
77
78 fn __hash__(&self) -> isize {
79 *self as isize
80 }
81
82 fn __str__(&self) -> String {
83 format!("{}", *self as u8 as char)
84 }
85
86 fn __repr__(&self) -> String {
87 format!("<Action.{}: '{}'>", self.name(), self.value())
88 }
89
90 #[getter]
91 fn name(&self) -> String {
92 self.as_ref().to_ascii_uppercase()
93 }
94
95 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
96 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
97 return false;
98 };
99 self.eq(&other_enum)
100 }
101
102 #[getter]
103 fn value(&self) -> String {
104 self.__str__()
105 }
106
107 #[classmethod]
108 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
109 EnumIterator::new::<Self>(py)
110 }
111
112 #[classmethod]
113 #[pyo3(name = "from_str")]
114 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
115 Self::try_from(value as u8).map_err(to_py_err)
116 }
117}
118
119#[pymethods]
120impl InstrumentClass {
121 #[new]
122 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
123 let Ok(i) = value.extract::<u8>() else {
124 let t = Self::type_object(py);
125 let c = value.extract::<char>().map_err(to_py_err)?;
126 return Self::py_from_str(&t, c);
127 };
128 Self::try_from(i).map_err(to_py_err)
129 }
130
131 fn __hash__(&self) -> isize {
132 *self as isize
133 }
134
135 fn __str__(&self) -> String {
136 format!("{}", *self as u8 as char)
137 }
138
139 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
140 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
141 return false;
142 };
143 self.eq(&other_enum)
144 }
145
146 #[getter]
147 fn value(&self) -> String {
148 self.__str__()
149 }
150
151 #[classmethod]
152 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
153 EnumIterator::new::<Self>(py)
154 }
155
156 #[classmethod]
157 #[pyo3(name = "from_str")]
158 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
159 Self::try_from(value as u8).map_err(to_py_err)
160 }
161}
162
163#[pymethods]
164impl MatchAlgorithm {
165 #[new]
166 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
167 let Ok(i) = value.extract::<u8>() else {
168 let t = Self::type_object(py);
169 let c = value.extract::<char>().map_err(to_py_err)?;
170 return Self::py_from_str(&t, c);
171 };
172 Self::try_from(i).map_err(to_py_err)
173 }
174
175 fn __hash__(&self) -> isize {
176 *self as isize
177 }
178
179 fn __str__(&self) -> String {
180 format!("{}", *self as u8 as char)
181 }
182
183 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
184 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
185 return false;
186 };
187 self.eq(&other_enum)
188 }
189
190 #[getter]
191 fn value(&self) -> String {
192 self.__str__()
193 }
194
195 #[classmethod]
196 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
197 EnumIterator::new::<Self>(py)
198 }
199
200 #[classmethod]
201 #[pyo3(name = "from_str")]
202 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
203 Self::try_from(value as u8).map_err(to_py_err)
204 }
205}
206
207#[pymethods]
208impl UserDefinedInstrument {
209 #[new]
210 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
211 let Ok(i) = value.extract::<u8>() else {
212 let t = Self::type_object(py);
213 let c = value.extract::<char>().map_err(to_py_err)?;
214 return Self::py_from_str(&t, c);
215 };
216 Self::try_from(i).map_err(to_py_err)
217 }
218
219 fn __hash__(&self) -> isize {
220 *self as isize
221 }
222
223 fn __str__(&self) -> String {
224 format!("{}", *self as u8 as char)
225 }
226
227 fn __repr__(&self) -> String {
228 format!(
229 "<UserDefinedInstrument.{}: '{}'>",
230 self.name(),
231 self.value()
232 )
233 }
234
235 #[getter]
236 fn name(&self) -> String {
237 self.as_ref().to_ascii_uppercase()
238 }
239
240 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
241 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
242 return false;
243 };
244 self.eq(&other_enum)
245 }
246
247 #[getter]
248 fn value(&self) -> String {
249 self.__str__()
250 }
251
252 #[classmethod]
253 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
254 EnumIterator::new::<Self>(py)
255 }
256
257 #[classmethod]
258 #[pyo3(name = "from_str")]
259 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
260 Self::try_from(value as u8).map_err(to_py_err)
261 }
262}
263
264#[pymethods]
265impl SType {
266 #[new]
267 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
268 let t = Self::type_object(py);
269 Self::py_from_str(&t, value)
270 }
271
272 fn __hash__(&self) -> isize {
273 *self as isize
274 }
275
276 fn __str__(&self) -> &'static str {
277 self.as_str()
278 }
279
280 fn __repr__(&self) -> String {
281 format!("<SType.{}: '{}'>", self.name(), self.value(),)
282 }
283
284 #[getter]
285 fn name(&self) -> String {
286 self.as_str().to_uppercase()
287 }
288
289 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
290 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
291 return false;
292 };
293 self.eq(&other_enum)
294 }
295
296 #[getter]
297 fn value(&self) -> &'static str {
298 self.as_str()
299 }
300
301 #[classmethod]
302 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
303 EnumIterator::new::<Self>(py)
304 }
305
306 #[classmethod]
307 #[pyo3(name = "from_str")]
308 fn py_from_str(_: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
309 let value_str: String = value.str().and_then(|s| s.extract())?;
310 let tokenized = value_str.replace('-', "_").to_lowercase();
311 Ok(Self::from_str(&tokenized)?)
312 }
313}
314
315#[pymethods]
316impl RType {
317 #[new]
318 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
319 let t = Self::type_object(py);
320 Self::py_from_str(&t, value).or_else(|_| Self::py_from_int(&t, value))
321 }
322
323 fn __hash__(&self) -> isize {
324 *self as isize
325 }
326
327 fn __str__(&self) -> &'static str {
328 self.as_str()
329 }
330
331 fn __repr__(&self) -> String {
332 format!("<RType.{}: '{}'>", self.name(), self.value(),)
333 }
334
335 #[getter]
336 fn name(&self) -> String {
337 self.as_str().to_uppercase()
338 }
339
340 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
341 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
342 return false;
343 };
344 self.eq(&other_enum)
345 }
346
347 #[getter]
348 fn value(&self) -> u8 {
349 *self as u8
350 }
351
352 #[classmethod]
353 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
354 EnumIterator::new::<Self>(py)
355 }
356
357 #[classmethod]
358 #[pyo3(name = "from_str")]
359 fn py_from_str(_: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
360 let value_str: String = value.str().and_then(|s| s.extract())?;
361 let tokenized = value_str.replace('-', "_").to_lowercase();
362 Ok(Self::from_str(&tokenized)?)
363 }
364
365 #[classmethod]
366 #[pyo3(name = "from_int")]
367 fn py_from_int(_: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
368 let value: u8 = value.extract()?;
369 Self::try_from(value).map_err(to_py_err)
370 }
371
372 #[classmethod]
373 #[pyo3(name = "from_schema")]
374 fn py_from_schema(pytype: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
375 let schema: Schema = value
376 .extract()
377 .or_else(|_| Schema::py_from_str(&Schema::type_object(pytype.py()), value))
378 .map_err(to_py_err)?;
379 Ok(Self::from(schema))
380 }
381}
382
383#[pymethods]
384impl Schema {
385 #[new]
386 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
387 let t = Self::type_object(py);
388 Self::py_from_str(&t, value)
389 }
390
391 fn __hash__(&self) -> isize {
392 *self as isize
393 }
394
395 fn __str__(&self) -> &'static str {
396 self.as_str()
397 }
398
399 fn __repr__(&self) -> String {
400 format!("<Schema.{}: '{}'>", self.name(), self.value(),)
401 }
402
403 #[getter]
404 fn name(&self) -> String {
405 self.as_str().to_uppercase()
406 }
407
408 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
409 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
410 return false;
411 };
412 self.eq(&other_enum)
413 }
414
415 #[getter]
416 fn value(&self) -> &'static str {
417 self.as_str()
418 }
419
420 #[classmethod]
421 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
422 EnumIterator::new::<Self>(py)
423 }
424
425 #[classmethod]
426 #[pyo3(name = "from_str")]
427 fn py_from_str(_: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
428 let value_str: String = value.str().and_then(|s| s.extract())?;
429 let tokenized = value_str.replace('_', "-").to_lowercase();
430 Ok(Self::from_str(&tokenized)?)
431 }
432}
433
434#[pymethods]
435impl Encoding {
436 #[new]
437 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
438 let t = Self::type_object(py);
439 Self::py_from_str(&t, value)
440 }
441
442 fn __hash__(&self) -> isize {
443 *self as isize
444 }
445
446 fn __str__(&self) -> &'static str {
447 self.as_str()
448 }
449
450 fn __repr__(&self) -> String {
451 format!("<Encoding.{}: '{}'>", self.name(), self.value(),)
452 }
453
454 #[getter]
455 fn name(&self) -> String {
456 self.as_str().to_uppercase()
457 }
458
459 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
460 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
461 return false;
462 };
463 self.eq(&other_enum)
464 }
465
466 #[getter]
467 fn value(&self) -> &'static str {
468 self.as_str()
469 }
470
471 #[classmethod]
472 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
473 EnumIterator::new::<Self>(py)
474 }
475
476 #[classmethod]
477 #[pyo3(name = "from_str")]
478 fn py_from_str(_: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
479 let value_str: String = value.str().and_then(|s| s.extract())?;
480 let tokenized = value_str.to_lowercase();
481 Ok(Self::from_str(&tokenized)?)
482 }
483}
484
485#[pymethods]
486impl Compression {
487 #[new]
488 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
489 let t = Self::type_object(py);
490 Self::py_from_str(&t, value)
491 }
492
493 fn __hash__(&self) -> isize {
494 *self as isize
495 }
496
497 fn __str__(&self) -> &'static str {
498 self.as_str()
499 }
500
501 fn __repr__(&self) -> String {
502 format!("<Compression.{}: '{}'>", self.name(), self.value(),)
503 }
504
505 #[getter]
506 fn name(&self) -> String {
507 self.as_str().to_uppercase()
508 }
509
510 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
511 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
512 return false;
513 };
514 self.eq(&other_enum)
515 }
516
517 #[getter]
518 fn value(&self) -> &'static str {
519 self.as_str()
520 }
521
522 #[classmethod]
524 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
525 EnumIterator::new::<Self>(py)
526 }
527
528 #[classmethod]
529 #[pyo3(name = "from_str")]
530 fn py_from_str(_: &Bound<PyType>, value: &Bound<PyAny>) -> PyResult<Self> {
531 let value_str: String = value.str().and_then(|s| s.extract())?;
532 let tokenized = value_str.to_lowercase();
533 Ok(Self::from_str(&tokenized)?)
534 }
535}
536
537#[pymethods]
538impl SecurityUpdateAction {
539 #[new]
540 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
541 let Ok(i) = value.extract::<u8>() else {
542 let t = Self::type_object(py);
543 let c = value.extract::<char>().map_err(to_py_err)?;
544 return Self::py_from_str(&t, c);
545 };
546 Self::try_from(i).map_err(to_py_err)
547 }
548
549 fn __hash__(&self) -> isize {
550 *self as isize
551 }
552
553 fn __repr__(&self) -> String {
554 format!("<SecurityUpdateAction.{}: '{}'>", self.name(), self.value())
555 }
556
557 #[getter]
558 fn name(&self) -> String {
559 self.as_ref().to_ascii_uppercase()
560 }
561
562 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
563 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
564 return false;
565 };
566 self.eq(&other_enum)
567 }
568
569 #[getter]
570 fn value(&self) -> u16 {
571 *self as u16
572 }
573
574 #[classmethod]
575 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
576 EnumIterator::new::<Self>(py)
577 }
578
579 #[classmethod]
580 #[pyo3(name = "from_str")]
581 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
582 Self::try_from(value as u8).map_err(to_py_err)
583 }
584}
585
586#[pymethods]
587impl StatType {
588 #[new]
589 fn py_new(value: &Bound<PyAny>) -> PyResult<Self> {
590 let i = value.extract::<u16>().map_err(to_py_err)?;
591 Self::try_from(i).map_err(to_py_err)
592 }
593
594 fn __hash__(&self) -> isize {
595 *self as isize
596 }
597
598 fn __eq__(&self, other: &Bound<PyAny>) -> bool {
599 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(other)) else {
600 return false;
601 };
602 self.eq(&other_enum)
603 }
604
605 #[getter]
606 fn value(&self) -> u16 {
607 *self as u16
608 }
609
610 #[classmethod]
611 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
612 EnumIterator::new::<Self>(py)
613 }
614}
615
616#[pymethods]
617impl StatusAction {
618 #[new]
619 fn py_new(value: &Bound<PyAny>) -> PyResult<Self> {
620 let i = value.extract::<u16>().map_err(to_py_err)?;
621 Self::try_from(i).map_err(to_py_err)
622 }
623
624 fn __hash__(&self) -> isize {
625 *self as isize
626 }
627
628 fn __eq__(&self, other: &Bound<PyAny>) -> bool {
629 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(other)) else {
630 return false;
631 };
632 self.eq(&other_enum)
633 }
634
635 #[getter]
636 fn value(&self) -> u16 {
637 *self as u16
638 }
639
640 #[classmethod]
641 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
642 EnumIterator::new::<Self>(py)
643 }
644}
645
646#[pymethods]
647impl StatusReason {
648 #[new]
649 fn py_new(value: &Bound<PyAny>) -> PyResult<Self> {
650 let i = value.extract::<u16>().map_err(to_py_err)?;
651 Self::try_from(i).map_err(to_py_err)
652 }
653
654 fn __hash__(&self) -> isize {
655 *self as isize
656 }
657
658 fn __eq__(&self, other: &Bound<PyAny>) -> bool {
659 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(other)) else {
660 return false;
661 };
662 self.eq(&other_enum)
663 }
664
665 #[getter]
666 fn value(&self) -> u16 {
667 *self as u16
668 }
669
670 #[classmethod]
671 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
672 EnumIterator::new::<Self>(py)
673 }
674}
675
676#[pymethods]
677impl TradingEvent {
678 #[new]
679 fn py_new(value: &Bound<PyAny>) -> PyResult<Self> {
680 let i = value.extract::<u16>().map_err(to_py_err)?;
681 Self::try_from(i).map_err(to_py_err)
682 }
683
684 fn __hash__(&self) -> isize {
685 *self as isize
686 }
687
688 fn __eq__(&self, other: &Bound<PyAny>) -> bool {
689 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(other)) else {
690 return false;
691 };
692 self.eq(&other_enum)
693 }
694
695 #[getter]
696 fn value(&self) -> u16 {
697 *self as u16
698 }
699
700 #[classmethod]
701 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
702 EnumIterator::new::<Self>(py)
703 }
704}
705
706#[pymethods]
707impl TriState {
708 #[new]
709 fn py_new(py: Python<'_>, value: &Bound<PyAny>) -> PyResult<Self> {
710 let Ok(i) = value.extract::<u8>() else {
711 let t = Self::type_object(py);
712 let c = value.extract::<char>().map_err(to_py_err)?;
713 return Self::py_from_str(&t, c);
714 };
715 Self::try_from(i).map_err(to_py_err)
716 }
717
718 fn __hash__(&self) -> isize {
719 *self as isize
720 }
721
722 fn __str__(&self) -> String {
723 format!("{}", *self as u8 as char)
724 }
725
726 fn opt_bool(&self) -> Option<bool> {
727 Option::from(*self)
728 }
729
730 fn __eq__(&self, other: &Bound<PyAny>, py: Python<'_>) -> bool {
731 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(py, other)) else {
732 return false;
733 };
734 self.eq(&other_enum)
735 }
736
737 #[getter]
738 fn value(&self) -> String {
739 self.__str__()
740 }
741
742 #[classmethod]
743 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
744 EnumIterator::new::<Self>(py)
745 }
746
747 #[classmethod]
748 #[pyo3(name = "from_str")]
749 fn py_from_str(_: &Bound<PyType>, value: char) -> PyResult<Self> {
750 Self::try_from(value as u8).map_err(to_py_err)
751 }
752}
753
754#[pymethods]
755impl VersionUpgradePolicy {
756 fn __hash__(&self) -> isize {
757 *self as isize
758 }
759
760 #[classmethod]
761 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
762 EnumIterator::new::<Self>(py)
763 }
764}
765
766impl PyFieldDesc for SecurityUpdateAction {
767 fn field_dtypes(field_name: &str) -> Vec<(String, String)> {
768 vec![(field_name.to_owned(), "S1".to_owned())]
769 }
770}
771
772impl PyFieldDesc for UserDefinedInstrument {
773 fn field_dtypes(field_name: &str) -> Vec<(String, String)> {
774 vec![(field_name.to_owned(), "S1".to_owned())]
775 }
776}
777
778#[pymethods]
779impl ErrorCode {
780 #[new]
781 fn py_new(value: &Bound<PyAny>) -> PyResult<Self> {
782 let i = value.extract::<u8>().map_err(to_py_err)?;
783 Self::try_from(i).map_err(to_py_err)
784 }
785
786 fn __hash__(&self) -> isize {
787 *self as isize
788 }
789
790 fn __str__(&self) -> &'static str {
791 self.as_str()
792 }
793
794 fn __repr__(&self) -> String {
795 format!("<ErrorCode.{}: '{}'>", self.name(), self.value())
796 }
797
798 #[getter]
799 fn name(&self) -> String {
800 self.as_ref().to_ascii_uppercase()
801 }
802
803 fn __eq__(&self, other: &Bound<PyAny>) -> bool {
804 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(other)) else {
805 return false;
806 };
807 self.eq(&other_enum)
808 }
809
810 #[getter]
811 fn value(&self) -> &'static str {
812 self.as_str()
813 }
814
815 #[classmethod]
816 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
817 EnumIterator::new::<Self>(py)
818 }
819}
820
821#[pymethods]
822impl SystemCode {
823 #[new]
824 fn py_new(value: &Bound<PyAny>) -> PyResult<Self> {
825 let i = value.extract::<u8>().map_err(to_py_err)?;
826 Self::try_from(i).map_err(to_py_err)
827 }
828
829 fn __hash__(&self) -> isize {
830 *self as isize
831 }
832
833 fn __str__(&self) -> &'static str {
834 self.as_str()
835 }
836
837 fn __repr__(&self) -> String {
838 format!("<SystemCode.{}: '{}'>", self.name(), self.value())
839 }
840
841 #[getter]
842 fn name(&self) -> String {
843 self.as_ref().to_ascii_uppercase()
844 }
845
846 fn __eq__(&self, other: &Bound<PyAny>) -> bool {
847 let Ok(other_enum) = other.extract::<Self>().or_else(|_| Self::py_new(other)) else {
848 return false;
849 };
850 self.eq(&other_enum)
851 }
852
853 #[getter]
854 fn value(&self) -> &'static str {
855 self.as_str()
856 }
857
858 #[classmethod]
859 fn variants(_: &Bound<PyType>, py: Python<'_>) -> PyResult<EnumIterator> {
860 EnumIterator::new::<Self>(py)
861 }
862}