use crate::time::python::deltas::PyTimeDelta;
use crate::time::python::time::PyTime;
use crate::time::time_scales::TimeScale;
use lox_time::intervals::{
TimeInterval, complement_intervals, intersect_intervals, union_intervals,
};
use pyo3::exceptions::PyValueError;
use pyo3::prelude::*;
#[pyclass(name = "Interval", module = "lox_space", frozen, from_py_object)]
#[derive(Clone, Debug)]
pub struct PyInterval(pub TimeInterval<TimeScale>);
#[pymethods]
impl PyInterval {
#[new]
fn new(start: PyTime, end: PyTime) -> Self {
PyInterval(TimeInterval::new(start.0, end.0))
}
pub fn __repr__(&self) -> String {
format!(
"Interval({}, {})",
self.start().__repr__(),
self.end().__repr__(),
)
}
fn start(&self) -> PyTime {
PyTime(self.0.start())
}
fn end(&self) -> PyTime {
PyTime(self.0.end())
}
fn duration(&self) -> PyTimeDelta {
PyTimeDelta(self.0.duration())
}
fn is_empty(&self) -> bool {
self.0.is_empty()
}
fn contains_time(&self, time: PyTime) -> bool {
self.0.contains_time(time.0)
}
fn contains(&self, other: &PyInterval) -> bool {
self.0.contains(&other.0)
}
fn intersect(&self, other: PyInterval) -> PyInterval {
PyInterval(self.0.intersect(other.0))
}
fn overlaps(&self, other: PyInterval) -> bool {
self.0.overlaps(other.0)
}
fn step_by(&self, step: PyTimeDelta) -> PyResult<Vec<PyTime>> {
if step.0.is_zero() {
return Err(PyValueError::new_err("step must be non-zero"));
}
Ok(self.0.step_by(step.0).map(PyTime).collect())
}
fn linspace(&self, n: usize) -> PyResult<Vec<PyTime>> {
if n < 2 {
return Err(PyValueError::new_err("n must be >= 2"));
}
Ok(self.0.linspace(n).into_iter().map(PyTime).collect())
}
}
#[pyfunction]
#[pyo3(name = "intersect_intervals")]
pub fn py_intersect_intervals(a: Vec<PyInterval>, b: Vec<PyInterval>) -> Vec<PyInterval> {
let a: Vec<_> = a.into_iter().map(|i| i.0).collect();
let b: Vec<_> = b.into_iter().map(|i| i.0).collect();
intersect_intervals(&a, &b)
.into_iter()
.map(PyInterval)
.collect()
}
#[pyfunction]
#[pyo3(name = "union_intervals")]
pub fn py_union_intervals(a: Vec<PyInterval>, b: Vec<PyInterval>) -> Vec<PyInterval> {
let a: Vec<_> = a.into_iter().map(|i| i.0).collect();
let b: Vec<_> = b.into_iter().map(|i| i.0).collect();
union_intervals(&a, &b)
.into_iter()
.map(PyInterval)
.collect()
}
#[pyfunction]
#[pyo3(name = "complement_intervals")]
pub fn py_complement_intervals(intervals: Vec<PyInterval>, bound: PyInterval) -> Vec<PyInterval> {
let intervals: Vec<_> = intervals.into_iter().map(|i| i.0).collect();
complement_intervals(&intervals, bound.0)
.into_iter()
.map(PyInterval)
.collect()
}