#![allow(dead_code, non_snake_case, nonstandard_style)]
use bitis_lib::*;
use pyo3::prelude::*;
use pyo3::exceptions::PyException;
use pyo3::types::{PyBytes};
use super::messages;
// Base function
fn do_val_from<T: ValFromInto<U>, U>(v: &U) -> T {
T::val_from(v)
}
// *****************************************************************
// *****************************************************************
// Enums
{%+ for ce in d.enums ~%}
{%- if let Some(comment_impl) = ce.comment -%}
///{{comment_impl}}
{%- endif %}
#[pyclass]
#[derive(Debug, Clone)]
pub enum {{ ce.name }} {
{%- for cv in ce.values +%}
{{ cv|pascal_case }},
{%- endfor %}
}
impl std::fmt::Display for {{ ce.name }} {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self {
{%- for cv in ce.values +%}
{{ ce.name }}::{{ cv|pascal_case }} => { write!(f, "{{ ce.name }}::{{ cv|pascal_case }}") }, {% endfor %}
}
} }
impl ValFromInto<{{ ce.name }}> for messages::{{ ce.name }} {
fn val_into(&self) -> {{ ce.name }} {
match self.clone() {
{%- for cv in ce.values +%}
messages::{{ ce.name }}::{{ cv|pascal_case }} => {{ ce.name }}::{{ cv|pascal_case }}, {% endfor %}
}
}
fn val_from(v: &{{ ce.name }}) -> Self {
match v {
{%- for cv in ce.values +%}
{{ ce.name }}::{{ cv|pascal_case }} => messages::{{ ce.name }}::{{ cv|pascal_case }}, {% endfor %}
}
}
}
{%- endfor +%}
// *****************************************************************
// *****************************************************************
// *** Enums for oneof
{%+ for (_, coo) in d.oos %}
#[pyclass]
#[derive(Debug)]
#[allow(dead_code)]
pub enum {{ coo.name }} {
{%- for ca in coo.attributes +%}
{% include "pyclasses_oo_attr.py.rs.jinja" %}
{%- endfor %}
}
#[pyclass(eq, eq_int)]
#[derive(Debug, PartialEq)]
pub enum {{ coo.name }}Enum {
{%- for ca in coo.attributes +%}
{{ca.base.name|pascal_case}},
{%- endfor %}
}
#[pymethods]
impl {{ coo.name }} {
{%- for ca in coo.attributes +%}
#[staticmethod]
fn new_{{ca.base.name|snake_case}}({{ca.base.name|snake_case}}: {%+ if ca.is_msg || ca.is_oo +%}Py<{%- endif -%}
{{ ca.base_type_str|safe }}{%- if ca.is_msg || ca.is_oo -%}>{% endif %}) -> PyResult<Py<Self>> {
Ok(Python::with_gil(|_py| { Py::new(_py, Self::{{ca.base.name|pascal_case}}({{ca.base.name|snake_case}})) })?)
}
{%- endfor %}
fn __repr__(&self) -> String { format!("{}", self) }
}
impl {{ coo.name }} {
pub fn to_rust(&self) -> messages::{{ coo.name }} {
Python::with_gil(|_py| {
match self { {%- for ca in coo.attributes -%}
Self::{{ca.base.name|pascal_case}}(v) => messages::{{ coo.name }}::{{ca.base.name|pascal_case}}(do_val_from(v)),
{%+ endfor %}
}
})
}
pub fn from_rust_obj(d: &messages::{{ coo.name }}) -> PyResult<Self> {
let r = Python::with_gil(|_py| {
match d { {%- for ca in coo.attributes -%}
messages::{{ coo.name }}::{{ca.base.name|pascal_case}}(v) => Self::{{ca.base.name|pascal_case}}(v.val_into()),
{% endfor %}
}
});
Ok(r)
}
}
impl std::fmt::Display for {{ coo.name }} {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
match self { {%- for ca in coo.attributes -%}{%- if ca.is_msg || ca.is_oo +%}
{{ coo.name }}::{{ca.base.name|pascal_case}}(v) => {
Python::with_gil(|py| {
write!(f, "{{ coo.name }}({{ca.base.name|pascal_case}}({})", v.borrow(py).__repr__()) }
)},
{%- else +%}
{{ coo.name }}::{{ca.base.name|pascal_case}}(v) => { write!(f, "{{ coo.name }}({{ca.base.name|pascal_case}}({}))", v) },
{%- endif -%}{%- endfor %}
}
}
}
impl ValFromInto<Py<{{coo.name}}>> for messages::{{coo.name}} {
fn val_into(self: &Self) -> Py<{{coo.name}}> {
Python::with_gil(|_py| { Py::new(_py, {{coo.name}}::from_rust_obj(self).unwrap()).unwrap() })
}
fn val_from(val: &Py<{{coo.name}}>) -> Self {
Python::with_gil(|_py| { val.borrow(_py).to_rust() })
}
}
{% endfor +%}
// *****************************************************************
// *****************************************************************
// *** Messages
{% for cm in d.msgs ~%}
{%- if let Some(comment_impl) = cm.comment -%}
///{{comment_impl}}
{%- endif %}
#[pyclass]
#[derive(Debug)]
pub struct {{cm.name}} {
// lala
{% if let Some(p) = cm.parent -%}// parent: {{ p }}{%- endif -%}
{% for ca in cm.attributes +%}
{%- if let Some(comment_impl) = ca.base.comment -%}
//{{comment_impl}}
{%- endif -%}
{# !ca.is_py_wrapped #}
{%- if !ca.is_oo +%} #[pyo3(get, set)]
{%+ endif +%} pub {{ca.base.name}}: {% include "pyclasses_attr.py.rs.jinja" %}
{% endfor -%}
}
#[pymethods]
impl {{cm.name}} {
#[new] #[allow(non_snake_case)]
pub fn __new__(
{%- for ca in cm.attributes +%} {{ca.base.name}}: {% include "pyclasses_attr.py.rs.jinja" %}{%- endfor -%}) -> Self {
Self{ {%- for ca in cm.attributes +%} {{ca.base.name}}: {{ca.base.name}}.into(),{%- endfor +%} }
}
#[staticmethod]
pub fn default() -> PyResult<Self> { Self::from_rust_obj(&Default::default()) }
pub fn serialize(&self, py: Python) -> (PyObject, u64, u64) {
let msg = self.to_rust();
let r = serialize(&msg);
(PyBytes::new(py, &r.0).into(), r.1.total_bits, r.1.total_bytes)
}
#[staticmethod]
pub fn deserialize(_py: Python, data: Bound<'_, PyBytes>) -> PyResult<Self> {
let dv: Vec<u8> = data.extract()?;
let v = match deserialize::<messages::{{cm.name}}>(&dv) {
Some(v) => v, None => return Err(PyErr::new::<PyException, _>("Error when deserializing {{cm.name}}"))
};
Self::from_rust_obj(&v.0)
}
pub fn __repr__(&self) -> String {
format!("{}", self)
}
{% for ca in cm.attributes +%}{% if ca.is_oo %}{%- if let Some(coo) = d.oos.get(ca.rust_type_str) +%}
#[getter]
pub fn {{ca.base.name|snake_case}}_oo(&self) -> {{ca.rust_type_str}}Enum {
match self.{{ca.base.name|snake_case}}.get() {
{%- for caa in coo.attributes +%}
{{ca.rust_type_str}}::{{caa.base.name|pascal_case}}(_) => {{ca.rust_type_str}}Enum::{{caa.base.name|pascal_case}},
{%- endfor +%}
} }
{%- for caa in coo.attributes +%}
#[getter({{ca.base.name|snake_case}}_{{caa.base.name|snake_case}})]
fn {{ca.base.name|snake_case}}_get_{{caa.base.name|snake_case}}(&self) -> Option<{%- if !caa.is_enum -%}&{%- endif -%}
{%- if caa.is_msg || caa.is_oo -%}Py<{%endif%}{{caa.base_type_str|safe}}{%- if caa.is_msg || caa.is_oo -%}>{%endif%}> {
match self.{{ca.base.name|snake_case}}.get() {
{{ca.rust_type_str}}::{{caa.base.name|pascal_case}}(v) => Some(v{%- if caa.is_enum -%}.clone(){%- endif -%}), _ => None
} }
#[setter({{ca.base.name|snake_case}}_{{caa.base.name|snake_case}})]
fn {{ca.base.name|snake_case}}_set_{{caa.base.name|snake_case}}(&mut self, v: {%- if caa.is_msg || caa.is_oo -%}
Py<{%endif%}{{caa.base_type_str|safe}}{%- if caa.is_msg || caa.is_oo -%}>{%endif%}) -> PyResult<()> {
Python::with_gil(|py| {
self.{{ca.base.name|snake_case}} = Py::new(py, {{ca.rust_type_str}}::{{caa.base.name|pascal_case}}(v))?;
Ok(())
})
}
{%- endfor -%}{%+ endif -%}{%+ endif -%}{%- endfor %}
}
impl {{cm.name}} {
pub fn to_rust(&self) -> messages::{{cm.name}} {
Python::with_gil(|_py| {
messages::{{cm.name}}{ {%- for ca in cm.attributes +%} {{ca.base.name}}: do_val_from(&self.{{ca.base.name}}), {%- endfor -%}}
})
}
pub fn from_rust_obj(_d: &messages::{{cm.name}}) -> PyResult<Self> {
let r = Python::with_gil(|_py| { Self{ {%- for ca in cm.attributes +%} {{ca.base.name}}: _d.{{ca.base.name}}.val_into(), {%- endfor -%}} });
Ok(r)
}
}
impl std::fmt::Display for {{cm.name}} {
fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
Python::with_gil(|_py| {
let t = self.to_rust();
write!(f, "{}", t)
})
}
}
impl ValFromInto<Py<{{cm.name}}>> for messages::{{cm.name}} {
fn val_into(self: &Self) -> Py<{{cm.name}}> {
Python::with_gil(|_py| { Py::new(_py, {{cm.name}}::from_rust_obj(self).unwrap()).unwrap() })
}
fn val_from(val: &Py<{{cm.name}}>) -> Self {
Python::with_gil(|_py| { val.borrow(_py).to_rust() })
}
}
{% endfor %}