feat!(core): Change Signal to be a sumtype

We want to be able to reason about if a signal is empty, constant, or sampled
at compile time without using any trait objects. Moreover, the core Argus
library shouldn't care about how it deals with interfacing with other languages
like Python. Thus, we remove the need for having an `AnySignal` type and what
not.
This commit is contained in:
Anand Balakrishnan 2023-04-14 10:53:38 -07:00
parent a6a3805107
commit 4431b79bcd
No known key found for this signature in database
10 changed files with 442 additions and 966 deletions

View file

@ -1,17 +1,23 @@
use std::iter::Zip;
use std::iter::{zip, Zip};
use std::time::Duration;
use super::Signal;
pub struct Iter<'a, T> {
iter: Zip<core::slice::Iter<'a, Duration>, core::slice::Iter<'a, T>>,
#[derive(Debug, Default)]
pub enum Iter<'a, T> {
#[default]
Empty,
Iter(Zip<core::slice::Iter<'a, Duration>, core::slice::Iter<'a, T>>),
}
impl<'a, T> Iterator for Iter<'a, T> {
type Item = (&'a Duration, &'a T);
fn next(&mut self) -> Option<Self::Item> {
self.iter.next()
match self {
Iter::Empty => None,
Iter::Iter(iter) => iter.next(),
}
}
}
@ -20,8 +26,10 @@ impl<'a, T> IntoIterator for &'a Signal<T> {
type Item = <Self::IntoIter as Iterator>::Item;
fn into_iter(self) -> Self::IntoIter {
Iter {
iter: self.time_points.iter().zip(self.values.iter()),
match self {
Signal::Empty => Iter::default(),
Signal::Constant { value: _ } => Iter::default(),
Signal::Sampled { values, time_points } => Iter::Iter(zip(time_points, values)),
}
}
}