feat!(py): expose boolean semantics to Python
This commit is contained in:
parent
c42f892099
commit
e6ef427e2f
8 changed files with 221 additions and 40 deletions
|
|
@ -11,5 +11,7 @@ crate-type = ["cdylib"]
|
||||||
argus-core = { version = "0.1.0", path = "../argus-core" }
|
argus-core = { version = "0.1.0", path = "../argus-core" }
|
||||||
argus-semantics = { version = "0.1.0", path = "../argus-semantics" }
|
argus-semantics = { version = "0.1.0", path = "../argus-semantics" }
|
||||||
derive_more = "0.99.17"
|
derive_more = "0.99.17"
|
||||||
|
log = "0.4.17"
|
||||||
paste = "1.0.12"
|
paste = "1.0.12"
|
||||||
pyo3 = "0.18.1"
|
pyo3 = "0.18.1"
|
||||||
|
pyo3-log = "0.8.1"
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
from argus import _argus
|
from argus import _argus
|
||||||
from argus._argus import *
|
from argus._argus import * # noqa: F401
|
||||||
|
|
||||||
__all__ = []
|
__all__ = []
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -158,3 +158,11 @@ class FloatSignal(Signal):
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def from_samples(samples: List[Tuple[float, float]]) -> FloatSignal: ...
|
def from_samples(samples: List[Tuple[float, float]]) -> FloatSignal: ...
|
||||||
def push(self, time, value): ...
|
def push(self, time, value): ...
|
||||||
|
|
||||||
|
@final
|
||||||
|
class Trace: ...
|
||||||
|
|
||||||
|
@final
|
||||||
|
class BooleanSemantics:
|
||||||
|
@staticmethod
|
||||||
|
def eval(expr: BoolExpr, trace: Trace) -> BoolSignal: ...
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,84 @@ classifiers = [
|
||||||
"Programming Language :: Python :: Implementation :: PyPy",
|
"Programming Language :: Python :: Implementation :: PyPy",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
|
||||||
|
dev = [
|
||||||
|
# Type check
|
||||||
|
"mypy",
|
||||||
|
# Lint code
|
||||||
|
"Flake8-pyproject",
|
||||||
|
"ruff",
|
||||||
|
# Find likely bugs
|
||||||
|
"flake8-bugbear",
|
||||||
|
# Sort imports
|
||||||
|
"isort",
|
||||||
|
# Reformat
|
||||||
|
"black",
|
||||||
|
]
|
||||||
|
|
||||||
[tool.maturin]
|
[tool.maturin]
|
||||||
features = ["pyo3/extension-module"]
|
features = ["pyo3/extension-module"]
|
||||||
module-name = "argus._argus"
|
module-name = "argus._argus"
|
||||||
|
|
||||||
|
[tool.pyright]
|
||||||
|
include = ["argus/", "examples/"]
|
||||||
|
|
||||||
|
[tool.mypy]
|
||||||
|
# ignore_missing_imports = true
|
||||||
|
show_error_codes = true
|
||||||
|
|
||||||
|
[tool.ruff]
|
||||||
|
line-length = 127
|
||||||
|
select = ["E", "F", "W", "N"]
|
||||||
|
ignore = ["F403"]
|
||||||
|
|
||||||
|
[tool.flake8]
|
||||||
|
# line breaks before and after binary operators
|
||||||
|
# ignore explicit stack level
|
||||||
|
ignore = ["W503", "W504", "E203", "E231", "C901", "F403"]
|
||||||
|
# Ignore import not used when aliases are defined
|
||||||
|
exclude = [
|
||||||
|
# No need to traverse our git directory
|
||||||
|
".git/",
|
||||||
|
# There's no value in checking cache directories
|
||||||
|
"__pycache__/",
|
||||||
|
# Don't check the doc
|
||||||
|
"docs/",
|
||||||
|
# This contains our built documentation
|
||||||
|
"build/",
|
||||||
|
# This contains builds of flake8 that we don't want to check
|
||||||
|
"dist/",
|
||||||
|
"*.egg-info",
|
||||||
|
# Artifacts generated by linters and type checkers
|
||||||
|
".mypy_cache/",
|
||||||
|
".ruff_cache/",
|
||||||
|
]
|
||||||
|
max-complexity = 10
|
||||||
|
max-line-length = 127
|
||||||
|
|
||||||
|
[tool.isort]
|
||||||
|
profile = "black"
|
||||||
|
line_length = 127
|
||||||
|
skip_gitignore = false
|
||||||
|
group_by_package = true
|
||||||
|
src_paths = ["argus", "examples/"]
|
||||||
|
extend_skip = [
|
||||||
|
# No need to traverse our git directory
|
||||||
|
".git/",
|
||||||
|
# There's no value in checking cache directories
|
||||||
|
"__pycache__/",
|
||||||
|
# Don't check the doc
|
||||||
|
"docs/",
|
||||||
|
# This contains our built documentation
|
||||||
|
"build/",
|
||||||
|
# This contains builds of flake8 that we don't want to check
|
||||||
|
"dist/",
|
||||||
|
"*.egg-info",
|
||||||
|
# Artifacts generated by linters and type checkers
|
||||||
|
".mypy_cache/",
|
||||||
|
".ruff_cache/",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.black]
|
||||||
|
line-length = 127
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ use pyo3::pyclass::CompareOp;
|
||||||
/// expressions supported in Argus (literals, arithmetic, and so on).
|
/// expressions supported in Argus (literals, arithmetic, and so on).
|
||||||
#[pyclass(name = "NumExpr", subclass, module = "argus")]
|
#[pyclass(name = "NumExpr", subclass, module = "argus")]
|
||||||
#[derive(Debug, Clone, derive_more::From)]
|
#[derive(Debug, Clone, derive_more::From)]
|
||||||
struct PyNumExpr(Box<NumExpr>);
|
pub struct PyNumExpr(pub Box<NumExpr>);
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl PyNumExpr {
|
impl PyNumExpr {
|
||||||
|
|
@ -55,7 +55,7 @@ impl PyNumExpr {
|
||||||
|
|
||||||
/// Create a constant integer expression
|
/// Create a constant integer expression
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct ConstInt;
|
pub struct ConstInt;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl ConstInt {
|
impl ConstInt {
|
||||||
|
|
@ -72,7 +72,7 @@ impl ConstInt {
|
||||||
/// Negating an unsigned integer during evaluation _may_ lead to the evaluation method
|
/// Negating an unsigned integer during evaluation _may_ lead to the evaluation method
|
||||||
/// panicking.
|
/// panicking.
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct ConstUInt;
|
pub struct ConstUInt;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl ConstUInt {
|
impl ConstUInt {
|
||||||
|
|
@ -84,7 +84,7 @@ impl ConstUInt {
|
||||||
|
|
||||||
/// Create a constant floating point number expression.
|
/// Create a constant floating point number expression.
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct ConstFloat;
|
pub struct ConstFloat;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl ConstFloat {
|
impl ConstFloat {
|
||||||
|
|
@ -96,7 +96,7 @@ impl ConstFloat {
|
||||||
|
|
||||||
/// Create a integer variable
|
/// Create a integer variable
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct VarInt;
|
pub struct VarInt;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl VarInt {
|
impl VarInt {
|
||||||
|
|
@ -108,7 +108,7 @@ impl VarInt {
|
||||||
|
|
||||||
/// Create an _unsigned_ integer variable
|
/// Create an _unsigned_ integer variable
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct VarUInt;
|
pub struct VarUInt;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl VarUInt {
|
impl VarUInt {
|
||||||
|
|
@ -120,7 +120,7 @@ impl VarUInt {
|
||||||
|
|
||||||
/// Create a float variable
|
/// Create a float variable
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct VarFloat;
|
pub struct VarFloat;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl VarFloat {
|
impl VarFloat {
|
||||||
|
|
@ -132,7 +132,7 @@ impl VarFloat {
|
||||||
|
|
||||||
/// Create a numeric negation expression
|
/// Create a numeric negation expression
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct Negate;
|
pub struct Negate;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Negate {
|
impl Negate {
|
||||||
|
|
@ -147,7 +147,7 @@ impl Negate {
|
||||||
///
|
///
|
||||||
/// This expression is an `n`-ary expression that takes
|
/// This expression is an `n`-ary expression that takes
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct Add;
|
pub struct Add;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Add {
|
impl Add {
|
||||||
|
|
@ -159,7 +159,7 @@ impl Add {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct Sub;
|
pub struct Sub;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Sub {
|
impl Sub {
|
||||||
|
|
@ -172,7 +172,7 @@ impl Sub {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct Mul;
|
pub struct Mul;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Mul {
|
impl Mul {
|
||||||
|
|
@ -184,7 +184,7 @@ impl Mul {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct Div;
|
pub struct Div;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Div {
|
impl Div {
|
||||||
|
|
@ -197,7 +197,7 @@ impl Div {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyNumExpr, module = "argus")]
|
#[pyclass(extends=PyNumExpr, module = "argus")]
|
||||||
struct Abs;
|
pub struct Abs;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Abs {
|
impl Abs {
|
||||||
|
|
@ -210,7 +210,7 @@ impl Abs {
|
||||||
|
|
||||||
#[pyclass(name = "BoolExpr", subclass, module = "argus")]
|
#[pyclass(name = "BoolExpr", subclass, module = "argus")]
|
||||||
#[derive(Debug, Clone, derive_more::From)]
|
#[derive(Debug, Clone, derive_more::From)]
|
||||||
struct PyBoolExpr(Box<BoolExpr>);
|
pub struct PyBoolExpr(pub Box<BoolExpr>);
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl PyBoolExpr {
|
impl PyBoolExpr {
|
||||||
|
|
@ -232,7 +232,7 @@ impl PyBoolExpr {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct ConstBool;
|
pub struct ConstBool;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl ConstBool {
|
impl ConstBool {
|
||||||
|
|
@ -243,7 +243,7 @@ impl ConstBool {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct VarBool;
|
pub struct VarBool;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl VarBool {
|
impl VarBool {
|
||||||
|
|
@ -254,11 +254,11 @@ impl VarBool {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Cmp;
|
pub struct Cmp;
|
||||||
|
|
||||||
#[pyclass(module = "argus")]
|
#[pyclass(module = "argus")]
|
||||||
#[derive(Debug, Copy, Clone, derive_more::From)]
|
#[derive(Debug, Copy, Clone, derive_more::From)]
|
||||||
struct PyOrdering(Ordering);
|
pub struct PyOrdering(Ordering);
|
||||||
|
|
||||||
impl Cmp {
|
impl Cmp {
|
||||||
fn new(op: PyOrdering, lhs: PyNumExpr, rhs: PyNumExpr) -> (Self, PyBoolExpr) {
|
fn new(op: PyOrdering, lhs: PyNumExpr, rhs: PyNumExpr) -> (Self, PyBoolExpr) {
|
||||||
|
|
@ -303,7 +303,7 @@ impl Cmp {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Not;
|
pub struct Not;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Not {
|
impl Not {
|
||||||
|
|
@ -315,7 +315,7 @@ impl Not {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct And;
|
pub struct And;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl And {
|
impl And {
|
||||||
|
|
@ -327,7 +327,7 @@ impl And {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Or;
|
pub struct Or;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Or {
|
impl Or {
|
||||||
|
|
@ -339,7 +339,7 @@ impl Or {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Next;
|
pub struct Next;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Next {
|
impl Next {
|
||||||
|
|
@ -351,7 +351,7 @@ impl Next {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Always;
|
pub struct Always;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Always {
|
impl Always {
|
||||||
|
|
@ -363,7 +363,7 @@ impl Always {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Eventually;
|
pub struct Eventually;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Eventually {
|
impl Eventually {
|
||||||
|
|
@ -375,7 +375,7 @@ impl Eventually {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
#[pyclass(extends=PyBoolExpr, module = "argus")]
|
||||||
struct Until;
|
pub struct Until;
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Until {
|
impl Until {
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@ impl From<PyArgusError> for PyErr {
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
#[pyo3(name = "_argus")]
|
#[pyo3(name = "_argus")]
|
||||||
fn pyargus(py: Python, m: &PyModule) -> PyResult<()> {
|
fn pyargus(py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
|
pyo3_log::init();
|
||||||
|
|
||||||
expr::init(py, m)?;
|
expr::init(py, m)?;
|
||||||
signals::init(py, m)?;
|
signals::init(py, m)?;
|
||||||
semantics::init(py, m)?;
|
semantics::init(py, m)?;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,102 @@
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use argus_core::signals::{AnySignal, Signal};
|
||||||
|
use argus_semantics::{BooleanSemantics, Semantics, Trace};
|
||||||
|
use pyo3::exceptions::PyTypeError;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
use pyo3::types::{PyDict, PyString};
|
||||||
|
|
||||||
|
use crate::expr::PyBoolExpr;
|
||||||
|
use crate::signals::{BoolSignal, FloatSignal, IntSignal, Kind, PySignal, UnsignedIntSignal};
|
||||||
|
use crate::PyArgusError;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, derive_more::From, derive_more::TryInto)]
|
||||||
|
#[try_into(owned, ref, ref_mut)]
|
||||||
|
enum SignalKind {
|
||||||
|
Bool(Signal<bool>),
|
||||||
|
Int(Signal<i64>),
|
||||||
|
UnsignedInt(Signal<u64>),
|
||||||
|
Float(Signal<f64>),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass(name = "Trace", module = "argus")]
|
||||||
|
#[derive(Debug, Clone, Default)]
|
||||||
|
pub struct PyTrace {
|
||||||
|
signals: HashMap<String, SignalKind>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl PyTrace {
|
||||||
|
#[new]
|
||||||
|
fn new(dict: &PyDict) -> PyResult<Self> {
|
||||||
|
let mut signals = HashMap::with_capacity(dict.len());
|
||||||
|
for (key, val) in dict {
|
||||||
|
let key: &PyString = key
|
||||||
|
.downcast()
|
||||||
|
.map_err(|e| PyTypeError::new_err(format!("expected dictionary with string keys for trace ({})", e)))?;
|
||||||
|
let val: &PyCell<PySignal> = val.downcast().map_err(|e| {
|
||||||
|
PyTypeError::new_err(format!(
|
||||||
|
"expected `argus.Signal` value for key `{}` in trace ({})",
|
||||||
|
key, e
|
||||||
|
))
|
||||||
|
})?;
|
||||||
|
let kind = val.borrow().kind;
|
||||||
|
let signal: SignalKind = match kind {
|
||||||
|
Kind::Bool => val.downcast::<PyCell<BoolSignal>>().unwrap().borrow().0.clone().into(),
|
||||||
|
Kind::Int => val.downcast::<PyCell<IntSignal>>().unwrap().borrow().0.clone().into(),
|
||||||
|
Kind::UnsignedInt => val
|
||||||
|
.downcast::<PyCell<UnsignedIntSignal>>()
|
||||||
|
.unwrap()
|
||||||
|
.borrow()
|
||||||
|
.0
|
||||||
|
.clone()
|
||||||
|
.into(),
|
||||||
|
Kind::Float => val.downcast::<PyCell<FloatSignal>>().unwrap().borrow().0.clone().into(),
|
||||||
|
};
|
||||||
|
|
||||||
|
signals.insert(key.to_string(), signal);
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(Self { signals })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn __repr__(&self) -> String {
|
||||||
|
format!("{:?}", self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Trace for PyTrace {
|
||||||
|
fn signal_names(&self) -> Vec<&str> {
|
||||||
|
self.signals.keys().map(|key| key.as_str()).collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get<T: 'static>(&self, name: &str) -> Option<&Signal<T>> {
|
||||||
|
let kind = self.signals.get(name)?;
|
||||||
|
let signal: &dyn AnySignal = match kind {
|
||||||
|
SignalKind::Bool(sig) => sig,
|
||||||
|
SignalKind::Int(sig) => sig,
|
||||||
|
SignalKind::UnsignedInt(sig) => sig,
|
||||||
|
SignalKind::Float(sig) => sig,
|
||||||
|
};
|
||||||
|
signal.as_any().downcast_ref::<Signal<T>>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass(name = "BooleanSemantics")]
|
||||||
|
struct PyBooleanSemantics;
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl PyBooleanSemantics {
|
||||||
|
#[staticmethod]
|
||||||
|
fn eval(expr: &PyBoolExpr, trace: &PyTrace) -> PyResult<Py<BoolSignal>> {
|
||||||
|
let sig = BooleanSemantics::eval(&expr.0, trace, ()).map_err(PyArgusError::from)?;
|
||||||
|
Python::with_gil(|py| Py::new(py, (BoolSignal::from(sig), BoolSignal::super_type())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn init(_py: Python, m: &PyModule) -> PyResult<()> {
|
pub fn init(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
|
m.add_class::<PyBooleanSemantics>()?;
|
||||||
|
m.add_class::<PyTrace>()?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -6,32 +6,33 @@ use pyo3::prelude::*;
|
||||||
use crate::PyArgusError;
|
use crate::PyArgusError;
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
pub enum SignalKind {
|
pub enum Kind {
|
||||||
Bool,
|
Bool,
|
||||||
Int,
|
Int,
|
||||||
UnsignedInt,
|
UnsignedInt,
|
||||||
Float,
|
Float,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pyclass(name = "Signal", subclass)]
|
#[pyclass(name = "Signal", subclass, module = "argus")]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct PySignal {
|
pub struct PySignal {
|
||||||
pub kind: SignalKind,
|
pub kind: Kind,
|
||||||
pub interpolation: InterpolationMethod,
|
pub interpolation: InterpolationMethod,
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_signals {
|
macro_rules! impl_signals {
|
||||||
($ty_name:ident, $ty:ty) => {
|
($ty_name:ident, $ty:ty) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
#[pyclass(extends=PySignal)]
|
#[pyclass(extends=PySignal, module = "argus")]
|
||||||
pub struct [<$ty_name Signal>](Signal<$ty>);
|
#[derive(Debug, Clone, derive_more::From)]
|
||||||
|
pub struct [<$ty_name Signal>](pub Signal<$ty>);
|
||||||
|
|
||||||
impl [<$ty_name Signal>] {
|
impl [<$ty_name Signal>] {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn super_type() -> PySignal {
|
pub fn super_type() -> PySignal {
|
||||||
PySignal {
|
PySignal {
|
||||||
interpolation: InterpolationMethod::Linear,
|
interpolation: InterpolationMethod::Linear,
|
||||||
kind: SignalKind::$ty_name,
|
kind: Kind::$ty_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -72,13 +73,7 @@ macro_rules! impl_signals {
|
||||||
Python::with_gil(|py| {
|
Python::with_gil(|py| {
|
||||||
Py::new(
|
Py::new(
|
||||||
py,
|
py,
|
||||||
(
|
(Self(ret), Self::super_type())
|
||||||
Self(ret),
|
|
||||||
PySignal {
|
|
||||||
interpolation: InterpolationMethod::Linear,
|
|
||||||
kind: SignalKind::$ty_name,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue