nautilus_model/python/identifiers/
symbol.rs1#![allow(deprecated)]
17use std::{
21 collections::hash_map::DefaultHasher,
22 hash::{Hash, Hasher},
23};
24
25use nautilus_core::python::to_pyvalue_err;
26use pyo3::{
27 prelude::*,
28 pyclass::CompareOp,
29 types::{PyString, PyTuple},
30};
31
32use crate::identifiers::symbol::Symbol;
33
34#[pymethods]
35impl Symbol {
36 #[new]
37 fn py_new(value: &str) -> PyResult<Self> {
38 Self::new_checked(value).map_err(to_pyvalue_err)
39 }
40
41 #[staticmethod]
42 fn _safe_constructor() -> Self {
43 Self::from("NULL")
44 }
45
46 fn __setstate__(&mut self, state: &Bound<'_, PyAny>) -> PyResult<()> {
47 let py_tuple: &Bound<'_, PyTuple> = state.downcast::<PyTuple>()?;
48 let binding = py_tuple.get_item(0)?;
49 let value = binding.downcast::<PyString>()?.extract::<&str>()?;
50 self.set_inner(value);
51 Ok(())
52 }
53
54 fn __getstate__(&self, py: Python) -> PyResult<PyObject> {
55 Ok((self.to_string(),).to_object(py))
56 }
57
58 fn __reduce__(&self, py: Python) -> PyResult<PyObject> {
59 let safe_constructor = py.get_type::<Self>().getattr("_safe_constructor")?;
60 let state = self.__getstate__(py)?;
61 Ok((safe_constructor, PyTuple::empty(py), state).to_object(py))
62 }
63
64 fn __richcmp__(&self, other: PyObject, op: CompareOp, py: Python<'_>) -> Py<PyAny> {
65 if let Ok(other) = other.extract::<Self>(py) {
66 match op {
67 CompareOp::Eq => self.eq(&other).into_py(py),
68 CompareOp::Ne => self.ne(&other).into_py(py),
69 CompareOp::Ge => self.ge(&other).into_py(py),
70 CompareOp::Gt => self.gt(&other).into_py(py),
71 CompareOp::Le => self.le(&other).into_py(py),
72 CompareOp::Lt => self.lt(&other).into_py(py),
73 }
74 } else {
75 py.NotImplemented()
76 }
77 }
78
79 fn __hash__(&self) -> isize {
80 let mut h = DefaultHasher::new();
81 self.hash(&mut h);
82 h.finish() as isize
83 }
84
85 fn __repr__(&self) -> String {
86 format!("{}('{}')", stringify!(Symbol), self)
87 }
88
89 fn __str__(&self) -> String {
90 self.to_string()
91 }
92
93 #[staticmethod]
94 #[pyo3(name = "from_str")]
95 fn py_from_str(value: &str) -> PyResult<Self> {
96 Self::new_checked(value).map_err(to_pyvalue_err)
97 }
98
99 #[getter]
100 #[pyo3(name = "value")]
101 fn py_value(&self) -> String {
102 self.to_string()
103 }
104
105 #[getter]
106 #[pyo3(name = "is_composite")]
107 fn py_is_composite(&self) -> bool {
108 self.is_composite()
109 }
110
111 #[getter]
112 #[pyo3(name = "root")]
113 fn py_root(&self) -> &str {
114 self.root()
115 }
116
117 #[getter]
118 #[pyo3(name = "topic")]
119 fn py_topic(&self) -> String {
120 self.topic()
121 }
122}
123
124impl ToPyObject for Symbol {
125 fn to_object(&self, py: Python) -> PyObject {
126 self.into_py(py)
127 }
128}