feat(core): add more fine grain casting operations for signals
This commit is contained in:
parent
4431b79bcd
commit
aa952c3151
3 changed files with 77 additions and 41 deletions
|
|
@ -29,6 +29,9 @@ pub enum Error {
|
||||||
|
|
||||||
#[error("incorrect signal type")]
|
#[error("incorrect signal type")]
|
||||||
InvalidSignalType,
|
InvalidSignalType,
|
||||||
|
|
||||||
|
#[error("invalid cast from {from} to {to}")]
|
||||||
|
InvalidCast { from: &'static str, to: &'static str },
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type ArgusError = Error;
|
pub type ArgusError = Error;
|
||||||
|
|
|
||||||
|
|
@ -1,11 +1,14 @@
|
||||||
use core::iter::zip;
|
use core::iter::zip;
|
||||||
|
|
||||||
use crate::signals::traits::SignalNumCast;
|
use crate::signals::traits::{SignalNumCast, TrySignalCast};
|
||||||
use crate::signals::Signal;
|
use crate::signals::Signal;
|
||||||
|
use crate::{ArgusError, ArgusResult};
|
||||||
|
|
||||||
macro_rules! impl_cast {
|
macro_rules! impl_cast_bool {
|
||||||
(bool => $to:ty) => {
|
([$( $to:ty ),*]) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
|
impl SignalNumCast for Signal<bool> {
|
||||||
|
$(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn [<to_ $to>](&self) -> Option<Signal<$to>> {
|
fn [<to_ $to>](&self) -> Option<Signal<$to>> {
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -21,10 +24,31 @@ macro_rules! impl_cast {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
impl TrySignalCast<Signal<$to>> for Signal<bool> {
|
||||||
|
fn try_cast(&self) -> ArgusResult<Signal<$to>> {
|
||||||
|
self.[<to_ $to>]().ok_or(ArgusError::InvalidCast {
|
||||||
|
from: std::any::type_name::<bool>(),
|
||||||
|
to: std::any::type_name::<$to>(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($from:ty => $to:ty) => {
|
() => {
|
||||||
|
impl_cast_bool!([i8, i16, i32, i64, u8, u16, u32, u64, f32, f64]);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! impl_cast {
|
||||||
|
($from:ty, [$( $to:ty ),*]) => {
|
||||||
paste::paste! {
|
paste::paste! {
|
||||||
|
impl SignalNumCast for Signal<$from> {
|
||||||
|
$(
|
||||||
#[inline]
|
#[inline]
|
||||||
fn [<to_ $to>](&self) -> Option<Signal<$to>> {
|
fn [<to_ $to>](&self) -> Option<Signal<$to>> {
|
||||||
match self {
|
match self {
|
||||||
|
|
@ -40,25 +64,28 @@ macro_rules! impl_cast {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
|
||||||
|
$(
|
||||||
|
impl TrySignalCast<Signal<$to>> for Signal<$from> {
|
||||||
|
fn try_cast(&self) -> ArgusResult<Signal<$to>> {
|
||||||
|
self.[<to_ $to>]().ok_or(ArgusError::InvalidCast {
|
||||||
|
from: std::any::type_name::<$from>(),
|
||||||
|
to: std::any::type_name::<$to>(),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)*
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
($from:ty) => {
|
($from:ty) => {
|
||||||
impl SignalNumCast for Signal<$from> {
|
impl_cast!($from, [i8, i16, i32, i64, u8, u16, u32, u64, f32, f64]);
|
||||||
impl_cast!($from => i8);
|
|
||||||
impl_cast!($from => i16);
|
|
||||||
impl_cast!($from => i32);
|
|
||||||
impl_cast!($from => i64);
|
|
||||||
impl_cast!($from => u8);
|
|
||||||
impl_cast!($from => u16);
|
|
||||||
impl_cast!($from => u32);
|
|
||||||
impl_cast!($from => u64);
|
|
||||||
impl_cast!($from => f32);
|
|
||||||
impl_cast!($from => f64);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_cast_bool!();
|
||||||
impl_cast!(i8);
|
impl_cast!(i8);
|
||||||
impl_cast!(i16);
|
impl_cast!(i16);
|
||||||
impl_cast!(i32);
|
impl_cast!(i32);
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ use std::time::Duration;
|
||||||
use paste::paste;
|
use paste::paste;
|
||||||
|
|
||||||
use super::{Sample, Signal};
|
use super::{Sample, Signal};
|
||||||
|
use crate::ArgusResult;
|
||||||
|
|
||||||
/// Trait for values that are linear interpolatable
|
/// Trait for values that are linear interpolatable
|
||||||
pub trait LinearInterpolatable {
|
pub trait LinearInterpolatable {
|
||||||
|
|
@ -113,7 +114,7 @@ pub trait SignalMinMax<Rhs = Self> {
|
||||||
fn max(&self, rhs: &Rhs) -> Self::Output;
|
fn max(&self, rhs: &Rhs) -> Self::Output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Trait for converting between numeric signal types
|
/// Trait for converting between signal types
|
||||||
pub trait SignalNumCast {
|
pub trait SignalNumCast {
|
||||||
fn to_i8(&self) -> Option<Signal<i8>>;
|
fn to_i8(&self) -> Option<Signal<i8>>;
|
||||||
fn to_i16(&self) -> Option<Signal<i16>>;
|
fn to_i16(&self) -> Option<Signal<i16>>;
|
||||||
|
|
@ -127,6 +128,11 @@ pub trait SignalNumCast {
|
||||||
fn to_f64(&self) -> Option<Signal<f64>>;
|
fn to_f64(&self) -> Option<Signal<f64>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait to cast signal onto some type
|
||||||
|
pub trait TrySignalCast<T>: Sized + SignalNumCast {
|
||||||
|
fn try_cast(&self) -> ArgusResult<T>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Trait for computing the absolute value of the samples in a signal
|
/// Trait for computing the absolute value of the samples in a signal
|
||||||
pub trait SignalAbs {
|
pub trait SignalAbs {
|
||||||
fn abs(&self) -> Self;
|
fn abs(&self) -> Self;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue