mirror of
https://github.com/askama-rs/askama.git
synced 2025-09-27 13:00:57 +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::num::{Saturating, Wrapping};
|
||||
use core::num::{self, FpCategory, Saturating, Wrapping};
|
||||
use core::ops::Deref;
|
||||
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>
|
||||
where
|
||||
T: Deref,
|
||||
@ -76,6 +77,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
/// An [`Option`] has a value if it is `Some`.
|
||||
impl<T> DefaultFilterable for Option<T> {
|
||||
type Filtered<'a>
|
||||
= &'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> {
|
||||
type Filtered<'a>
|
||||
= &'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 {
|
||||
type Filtered<'a>
|
||||
= &'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")]
|
||||
impl DefaultFilterable for alloc::string::String {
|
||||
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")]
|
||||
impl<T: DefaultFilterable + alloc::borrow::ToOwned + ?Sized> DefaultFilterable
|
||||
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> {
|
||||
type 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> {
|
||||
type Filtered<'a>
|
||||
= T::Filtered<'a>
|
||||
@ -183,6 +191,7 @@ impl<T: DefaultFilterable> DefaultFilterable for Saturating<T> {
|
||||
|
||||
macro_rules! impl_for_int {
|
||||
($($ty:ty)*) => { $(
|
||||
#[doc = concat!("A [`", stringify!($ty), "`] has a value if it is not `0`.")]
|
||||
impl DefaultFilterable for $ty {
|
||||
type Filtered<'a> = $ty;
|
||||
type Error = Infallible;
|
||||
@ -205,7 +214,8 @@ impl_for_int!(
|
||||
|
||||
macro_rules! impl_for_non_zero {
|
||||
($($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 Error = Infallible;
|
||||
|
||||
@ -222,6 +232,7 @@ impl_for_non_zero!(
|
||||
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 {
|
||||
type Filtered<'a> = bool;
|
||||
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