use crate::dynamic::{BSet, LeanVec};
use crate::time::UnitTimestamp;
use std::collections::BTreeMap;
use std::rc::Rc;
use std::sync::Arc;
use uuid::Uuid;
pub trait IsNone {
type Inner;
fn is_none(&self) -> bool;
fn unwrap_or_self(&self) -> &Self::Inner;
fn from_inner(inner: Self::Inner) -> Self;
}
impl<T> IsNone for Option<T> {
type Inner = T;
fn is_none(&self) -> bool {
self.is_none()
}
fn unwrap_or_self(&self) -> &Self::Inner {
self.as_ref()
.expect("IsNone::unwrap_or_self called on None")
}
fn from_inner(inner: Self::Inner) -> Self {
Some(inner)
}
}
#[macro_export]
macro_rules! never_none {
($($ty:ty),* $(,)?) => {
$(
impl $crate::utils::IsNone for $ty {
type Inner = $ty;
fn is_none(&self) -> bool { false }
fn unwrap_or_self(&self) -> &Self::Inner { self }
fn from_inner(inner: Self::Inner) -> Self { inner }
}
)*
};
}
never_none!(
(),
bool,
char,
i8,
i16,
i32,
i64,
i128,
u8,
u16,
u32,
u64,
u128,
f32,
f64,
usize,
isize,
String,
UnitTimestamp,
Uuid
);
#[macro_export]
macro_rules! never_none_1 {
($($wrapper:ident),* $(,)?) => {
$(
impl<T> $crate::utils::IsNone for $wrapper<T> {
type Inner = $wrapper<T>;
fn is_none(&self) -> bool { false }
fn unwrap_or_self(&self) -> &Self::Inner { self }
fn from_inner(inner: Self::Inner) -> Self { inner }
}
)*
};
}
never_none_1!(Vec, LeanVec, BSet,);
#[macro_export]
macro_rules! delegate_is_none {
($($wrapper:ident),* $(,)?) => {
$(
impl<T: $crate::utils::IsNone> $crate::utils::IsNone for $wrapper<T> {
type Inner = $wrapper<T>;
fn is_none(&self) -> bool {
false
}
fn unwrap_or_self(&self) -> &Self::Inner { self }
fn from_inner(inner: Self::Inner) -> Self { inner }
}
)*
};
}
delegate_is_none!(Box, Rc, Arc,);
#[macro_export]
macro_rules! never_none_tuples {
($($name:ident),+) => {
impl<$($name),+> IsNone for ($($name,)+) {
type Inner = ($($name,)+);
fn is_none(&self) -> bool {
false
}
fn unwrap_or_self(&self) -> &Self::Inner { self }
fn from_inner(inner: Self::Inner) -> Self { inner }
}
};
}
never_none_tuples!(A);
never_none_tuples!(A, B);
never_none_tuples!(A, B, C);
never_none_tuples!(A, B, C, D);
never_none_tuples!(A, B, C, D, E);
never_none_tuples!(A, B, C, D, E, F);
impl<K, V> IsNone for BTreeMap<K, V> {
type Inner = BTreeMap<K, V>;
fn is_none(&self) -> bool {
false
}
fn unwrap_or_self(&self) -> &Self::Inner {
self
}
fn from_inner(inner: Self::Inner) -> Self {
inner
}
}
#[cfg(test)]
mod test {
use feldera_macros::IsNone;
#[derive(IsNone)]
struct X {
_i: i32,
}
#[test]
fn x_not_none() {
use dbsp::utils::IsNone;
let x = X { _i: 0 };
assert!(!x.is_none());
}
}