mirror of
https://github.com/askama-rs/askama.git
synced 2025-10-02 07:20:55 +00:00
More tests for DefaultFilterable
+ impl for floats
This commit is contained in:
parent
ba7b0a7967
commit
564a8463ee
@ -1,5 +1,5 @@
|
|||||||
use core::convert::Infallible;
|
use core::convert::Infallible;
|
||||||
use core::num::{Saturating, Wrapping};
|
use core::num::{self, FpCategory, Saturating, Wrapping};
|
||||||
use core::ops::Deref;
|
use core::ops::Deref;
|
||||||
use core::pin::Pin;
|
use core::pin::Pin;
|
||||||
|
|
||||||
@ -58,6 +58,7 @@ impl_for_ref! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [pinned][Pin] reference has a value if the referenced data has a value.
|
||||||
impl<T> DefaultFilterable for Pin<T>
|
impl<T> DefaultFilterable for Pin<T>
|
||||||
where
|
where
|
||||||
T: Deref,
|
T: Deref,
|
||||||
@ -76,6 +77,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An [`Option`] has a value if it is `Some`.
|
||||||
impl<T> DefaultFilterable for Option<T> {
|
impl<T> DefaultFilterable for Option<T> {
|
||||||
type Filtered<'a>
|
type Filtered<'a>
|
||||||
= &'a T
|
= &'a T
|
||||||
@ -90,6 +92,7 @@ impl<T> DefaultFilterable for Option<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`Result`] has a value if it is `Ok`.
|
||||||
impl<T, E> DefaultFilterable for Result<T, E> {
|
impl<T, E> DefaultFilterable for Result<T, E> {
|
||||||
type Filtered<'a>
|
type Filtered<'a>
|
||||||
= &'a T
|
= &'a T
|
||||||
@ -104,6 +107,7 @@ impl<T, E> DefaultFilterable for Result<T, E> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`str`] has a value if it is not empty.
|
||||||
impl DefaultFilterable for str {
|
impl DefaultFilterable for str {
|
||||||
type Filtered<'a>
|
type Filtered<'a>
|
||||||
= &'a str
|
= &'a str
|
||||||
@ -121,6 +125,7 @@ impl DefaultFilterable for str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`String`][alloc::string::String] has a value if it is not empty.
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl DefaultFilterable for alloc::string::String {
|
impl DefaultFilterable for alloc::string::String {
|
||||||
type Filtered<'a>
|
type Filtered<'a>
|
||||||
@ -136,6 +141,7 @@ impl DefaultFilterable for alloc::string::String {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`Cow`][alloc::borrow::Cow] has a value if it's borrowed data has a value.
|
||||||
#[cfg(feature = "alloc")]
|
#[cfg(feature = "alloc")]
|
||||||
impl<T: DefaultFilterable + alloc::borrow::ToOwned + ?Sized> DefaultFilterable
|
impl<T: DefaultFilterable + alloc::borrow::ToOwned + ?Sized> DefaultFilterable
|
||||||
for alloc::borrow::Cow<'_, T>
|
for alloc::borrow::Cow<'_, T>
|
||||||
@ -153,6 +159,7 @@ impl<T: DefaultFilterable + alloc::borrow::ToOwned + ?Sized> DefaultFilterable
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`Wrapping`] integer has a value if it is not `0`.
|
||||||
impl<T: DefaultFilterable> DefaultFilterable for Wrapping<T> {
|
impl<T: DefaultFilterable> DefaultFilterable for Wrapping<T> {
|
||||||
type Filtered<'a>
|
type Filtered<'a>
|
||||||
= T::Filtered<'a>
|
= T::Filtered<'a>
|
||||||
@ -167,6 +174,7 @@ impl<T: DefaultFilterable> DefaultFilterable for Wrapping<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A [`Saturating`] integer has a value if it is not `0`.
|
||||||
impl<T: DefaultFilterable> DefaultFilterable for Saturating<T> {
|
impl<T: DefaultFilterable> DefaultFilterable for Saturating<T> {
|
||||||
type Filtered<'a>
|
type Filtered<'a>
|
||||||
= T::Filtered<'a>
|
= T::Filtered<'a>
|
||||||
@ -183,6 +191,7 @@ impl<T: DefaultFilterable> DefaultFilterable for Saturating<T> {
|
|||||||
|
|
||||||
macro_rules! impl_for_int {
|
macro_rules! impl_for_int {
|
||||||
($($ty:ty)*) => { $(
|
($($ty:ty)*) => { $(
|
||||||
|
#[doc = concat!("A [`", stringify!($ty), "`] has a value if it is not `0`.")]
|
||||||
impl DefaultFilterable for $ty {
|
impl DefaultFilterable for $ty {
|
||||||
type Filtered<'a> = $ty;
|
type Filtered<'a> = $ty;
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
@ -205,7 +214,8 @@ impl_for_int!(
|
|||||||
|
|
||||||
macro_rules! impl_for_non_zero {
|
macro_rules! impl_for_non_zero {
|
||||||
($($name:ident : $ty:ty)*) => { $(
|
($($name:ident : $ty:ty)*) => { $(
|
||||||
impl DefaultFilterable for core::num::$name {
|
#[doc = concat!("A [`", stringify!($name), "`][num::", stringify!($name),"] always has a value.")]
|
||||||
|
impl DefaultFilterable for num::$name {
|
||||||
type Filtered<'a> = $ty;
|
type Filtered<'a> = $ty;
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
|
|
||||||
@ -222,6 +232,7 @@ impl_for_non_zero!(
|
|||||||
NonZeroI8:i8 NonZeroI16:i16 NonZeroI32:i32 NonZeroI64:i64 NonZeroI128:i128 NonZeroIsize:isize
|
NonZeroI8:i8 NonZeroI16:i16 NonZeroI32:i32 NonZeroI64:i64 NonZeroI128:i128 NonZeroIsize:isize
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/// A `bool` has a value if it is [`true`].
|
||||||
impl DefaultFilterable for bool {
|
impl DefaultFilterable for bool {
|
||||||
type Filtered<'a> = bool;
|
type Filtered<'a> = bool;
|
||||||
type Error = Infallible;
|
type Error = Infallible;
|
||||||
@ -234,3 +245,159 @@ impl DefaultFilterable for bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An `f32` has a value if it is [`Normal`][FpCategory::Normal], i.e. it is not zero,
|
||||||
|
/// not sub-normal, not infinite and not NaN.
|
||||||
|
impl DefaultFilterable for f32 {
|
||||||
|
type Filtered<'a>
|
||||||
|
= Self
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn as_filtered(&self) -> Result<Option<Self::Filtered<'_>>, Self::Error> {
|
||||||
|
Ok((self.classify() == FpCategory::Normal).then_some(*self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// An `f64` has a value if it is [`Normal`](FpCategory::Normal), i.e. it is not zero,
|
||||||
|
/// not sub-normal, not infinite and not NaN.
|
||||||
|
impl DefaultFilterable for f64 {
|
||||||
|
type Filtered<'a>
|
||||||
|
= Self
|
||||||
|
where
|
||||||
|
Self: 'a;
|
||||||
|
|
||||||
|
type Error = Infallible;
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn as_filtered(&self) -> Result<Option<Self::Filtered<'_>>, Self::Error> {
|
||||||
|
Ok((self.classify() == FpCategory::Normal).then_some(*self))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
#[cfg(feature = "std")]
|
||||||
|
fn test_default_filterable() {
|
||||||
|
use std::borrow::Cow;
|
||||||
|
use std::rc::Rc;
|
||||||
|
use std::string::ToString;
|
||||||
|
use std::sync::{Arc, Mutex};
|
||||||
|
|
||||||
|
use assert_matches::assert_matches;
|
||||||
|
|
||||||
|
// integers
|
||||||
|
assert_matches!(0_u8.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_u16.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_u32.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_u64.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_u128.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_usize.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_i8.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_i16.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_i32.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_i64.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_i128.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_isize.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(1_u8.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_u16.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_u32.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_u64.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_u128.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_usize.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_i8.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_i16.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_i32.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_i64.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_i128.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(1_isize.as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!((-1_i8).as_filtered(), Ok(Some(-1)));
|
||||||
|
assert_matches!((-1_i16).as_filtered(), Ok(Some(-1)));
|
||||||
|
assert_matches!((-1_i32).as_filtered(), Ok(Some(-1)));
|
||||||
|
assert_matches!((-1_i64).as_filtered(), Ok(Some(-1)));
|
||||||
|
assert_matches!((-1_i128).as_filtered(), Ok(Some(-1)));
|
||||||
|
assert_matches!((-1_isize).as_filtered(), Ok(Some(-1)));
|
||||||
|
|
||||||
|
// floats
|
||||||
|
// -> zero
|
||||||
|
assert_matches!(0_f32.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(0_f64.as_filtered(), Ok(None));
|
||||||
|
// -> subnormal
|
||||||
|
assert_matches!((f32::MIN_POSITIVE / 2.0).as_filtered(), Ok(None));
|
||||||
|
assert_matches!((f64::MIN_POSITIVE / 2.0).as_filtered(), Ok(None));
|
||||||
|
// -> nan
|
||||||
|
assert_matches!(f32::NAN.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(f64::NAN.as_filtered(), Ok(None));
|
||||||
|
// -> infinite
|
||||||
|
assert_matches!(f32::NEG_INFINITY.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(f32::INFINITY.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(f64::NEG_INFINITY.as_filtered(), Ok(None));
|
||||||
|
assert_matches!(f64::INFINITY.as_filtered(), Ok(None));
|
||||||
|
// -> normal
|
||||||
|
assert_matches!(1_f32.as_filtered(), Ok(Some(1.0)));
|
||||||
|
assert_matches!((-1_f32).as_filtered(), Ok(Some(-1.0)));
|
||||||
|
assert_matches!(f32::MIN.as_filtered(), Ok(Some(f32::MIN)));
|
||||||
|
assert_matches!(f32::MIN_POSITIVE.as_filtered(), Ok(Some(f32::MIN_POSITIVE)));
|
||||||
|
assert_matches!(f32::MAX.as_filtered(), Ok(Some(f32::MAX)));
|
||||||
|
assert_matches!(1_f64.as_filtered(), Ok(Some(1.0)));
|
||||||
|
assert_matches!((-1_f64).as_filtered(), Ok(Some(-1.0)));
|
||||||
|
assert_matches!(f64::MIN.as_filtered(), Ok(Some(f64::MIN)));
|
||||||
|
assert_matches!(f64::MIN_POSITIVE.as_filtered(), Ok(Some(f64::MIN_POSITIVE)));
|
||||||
|
assert_matches!(f64::MAX.as_filtered(), Ok(Some(f64::MAX)));
|
||||||
|
|
||||||
|
// non-zero integers
|
||||||
|
assert_matches!(num::NonZeroU8::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroU16::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroU32::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroU64::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroU128::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(
|
||||||
|
num::NonZeroUsize::new(1).unwrap().as_filtered(),
|
||||||
|
Ok(Some(1))
|
||||||
|
);
|
||||||
|
assert_matches!(num::NonZeroI8::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroI16::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroI32::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroI64::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(num::NonZeroI128::new(1).unwrap().as_filtered(), Ok(Some(1)));
|
||||||
|
assert_matches!(
|
||||||
|
num::NonZeroIsize::new(1).unwrap().as_filtered(),
|
||||||
|
Ok(Some(1))
|
||||||
|
);
|
||||||
|
|
||||||
|
// strings
|
||||||
|
assert_matches!("".as_filtered(), Ok(None));
|
||||||
|
assert_matches!("hello".as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!("".to_string().as_filtered(), Ok(None));
|
||||||
|
assert_matches!("hello".to_string().as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!(Cow::Borrowed("").as_filtered(), Ok(None));
|
||||||
|
assert_matches!(Cow::Borrowed("hello").as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!(Cow::<str>::Owned("".to_string()).as_filtered(), Ok(None));
|
||||||
|
assert_matches!(
|
||||||
|
Cow::<str>::Owned("hello".to_string()).as_filtered(),
|
||||||
|
Ok(Some("hello"))
|
||||||
|
);
|
||||||
|
|
||||||
|
// results + options
|
||||||
|
assert_matches!(Ok::<(), ()>(()).as_filtered(), Ok(Some(())));
|
||||||
|
assert_matches!(Err::<(), ()>(()).as_filtered(), Ok(None));
|
||||||
|
assert_matches!(Some(()).as_filtered(), Ok(Some(())));
|
||||||
|
assert_matches!(None::<()>.as_filtered(), Ok(None));
|
||||||
|
|
||||||
|
// references
|
||||||
|
assert_matches!(Arc::new("").as_filtered(), Ok(None));
|
||||||
|
assert_matches!(Arc::new("hello").as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!(Arc::pin("").as_filtered(), Ok(None));
|
||||||
|
assert_matches!(Arc::pin("hello").as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!(Rc::new("").as_filtered(), Ok(None));
|
||||||
|
assert_matches!(Rc::new("hello").as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!(Rc::pin("").as_filtered(), Ok(None));
|
||||||
|
assert_matches!(Rc::pin("hello").as_filtered(), Ok(Some("hello")));
|
||||||
|
assert_matches!(Mutex::new("").try_lock().unwrap().as_filtered(), Ok(None));
|
||||||
|
assert_matches!(
|
||||||
|
Mutex::new("hello").try_lock().unwrap().as_filtered(),
|
||||||
|
Ok(Some("hello"))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user