tea_dtype/
isnone.rs

1use std::cmp::Ordering;
2
3#[cfg(feature = "time")]
4use tea_time::{DateTime, Time, TimeDelta, TimeUnitTrait};
5
6use super::cast::Cast;
7use super::number::Number;
8
9/// A trait for types that can represent a "none" or null-like state.
10///
11/// This trait is implemented by types that can be in a "none" state,
12/// similar to Rust's `Option` type. It provides methods for working
13/// with such types in a generic way.
14///
15/// # Type Parameters
16///
17/// * `Inner`: The inner type. For regular types `T`, `Inner` is `T` itself.
18///   For `Option<T>`, `Inner` is `T`. This allows `Option<T::Inner>` to be
19///   the same type for both `T` and `Option<T>`.
20///
21/// * `Cast<U>`: A type that represents the result of casting to another `IsNone` type.
22///   For regular types, `Cast<U>` is typically `U`. For `Option<T>`, `Cast<U>`
23///   is `Option<U>`. This allows operations like `Option<T>::cast<f64>()` to result
24///   in `Option<f64>`, while `T::cast<f64>()` results in `f64`.
25///
26/// # Required Methods
27///
28/// Implementors must define:
29/// - `is_none`: Check if the value is in the "none" state.
30/// - `none`: Create a new instance in the "none" state.
31/// - `to_opt`: Convert to an `Option<Inner>`.
32/// - `as_opt`: Get a reference as an `Option<&Inner>`.
33/// - `from_inner`: Create an instance from an `Inner` value.
34/// - `inner_cast`: Cast between different `IsNone` types.
35///
36/// # Provided Methods
37///
38/// The trait also provides default implementations for:
39/// - `from_opt`: Create an instance from an `Option<Inner>`.
40/// - `unwrap`: Get the inner value, panicking if none.
41/// - `not_none`: Check if the value is not in the "none" state.
42/// - `map`: Apply a function to the inner value if not none.
43pub trait IsNone: Clone
44where
45    Self: Sized,
46{
47    type Inner: IsNone<Inner = Self::Inner>;
48    type Cast<U: IsNone<Inner = U>>: IsNone<Inner = U>;
49
50    /// Checks if the value is in the "none" state.
51    ///
52    /// # Returns
53    ///
54    /// `true` if the value is in the "none" state, `false` otherwise.
55    fn is_none(&self) -> bool;
56
57    /// Creates a new instance of `Self` in the "none" state.
58    ///
59    /// This method is used to generate a value that represents the absence of a valid value,
60    /// similar to `None` in Rust's `Option` type.
61    ///
62    /// # Returns
63    ///
64    /// Returns a new instance of `Self` that is considered to be in the "none" state.
65    // TODO: some type doesn't have none value, so it should return a `TResult<Self>`
66    fn none() -> Self;
67
68    /// Converts the value to an `Option<Self::Inner>`.
69    ///
70    /// This method transforms the current value into an `Option` type, where:
71    /// - If the current value is in the "none" state, it returns `None`.
72    /// - Otherwise, it returns `Some(inner)`, where `inner` is the wrapped value.
73    ///
74    /// # Returns
75    ///
76    /// An `Option<Self::Inner>` representing the current value.
77    fn to_opt(self) -> Option<Self::Inner>;
78
79    /// Converts the value to an `Option<&Self::Inner>`.
80    ///
81    /// This method returns a reference to the inner value as an `Option` type, where:
82    /// - If the current value is in the "none" state, it returns `None`.
83    /// - Otherwise, it returns `Some(&inner)`, where `inner` is a reference to the wrapped value.
84    ///
85    /// # Returns
86    ///
87    /// An `Option<&Self::Inner>` representing a reference to the current value.
88    fn as_opt(&self) -> Option<&Self::Inner>;
89
90    /// Creates a new instance of `Self` from the given inner value.
91    ///
92    /// This method converts a value of type `Self::Inner` into `Self`.
93    /// For example, if `Self` is `f64`, `Self::Inner` is also `f64`, so this method
94    /// would essentially be an identity function. However, if `Self` is `Option<f64>`,
95    /// `Self::Inner` would be `f64`, so this method would wrap the `f64` value in `Some`.
96    ///
97    /// # Arguments
98    ///
99    /// * `inner` - The inner value to be converted.
100    ///
101    /// # Returns
102    ///
103    /// Returns a new instance of `Self` created from the provided inner value.
104    fn from_inner(inner: Self::Inner) -> Self;
105
106    /// Casts the inner type of `Self` to a new type `U`.
107    ///
108    /// This method allows for casting between different `IsNone` types, preserving the "none" state
109    /// if applicable. It uses the `Cast` trait to perform the actual type conversion.
110    ///
111    /// # Type Parameters
112    ///
113    /// * `U`: The target type, which must implement `IsNone` and have `Inner = U`.
114    ///
115    /// # Arguments
116    ///
117    /// * `inner`: The value of type `U` to be cast.
118    ///
119    /// # Returns
120    ///
121    /// Returns `Self::Cast<U>`, which is the result of casting `Self` to a type that can hold `U`.
122    fn inner_cast<U: IsNone<Inner = U>>(inner: U) -> Self::Cast<U>
123    where
124        Self::Inner: Cast<U::Inner>;
125
126    #[inline]
127    /// Creates a new instance of `Self` from an `Option<Self::Inner>`.
128    fn from_opt(opt: Option<Self::Inner>) -> Self {
129        opt.map_or_else(Self::none, Self::from_inner)
130    }
131
132    #[inline]
133    fn unwrap(self) -> Self::Inner {
134        self.to_opt().unwrap()
135    }
136
137    #[inline]
138    fn not_none(&self) -> bool {
139        !self.is_none()
140    }
141
142    /// Maps a function over the inner value of `Self`, if it exists.
143    ///
144    /// This method applies a given function to the inner value of `Self` if it's not none,
145    /// and wraps the result in a new `IsNone` type `U`. If `Self` is none, it returns
146    /// the none value of type `U`.
147    ///
148    /// # Type Parameters
149    ///
150    /// * `F`: The type of the mapping function.
151    /// * `U`: The target `IsNone` type.
152    ///
153    /// # Arguments
154    ///
155    /// * `self`: The `IsNone` value to map over.
156    /// * `f`: A function that takes `Self::Inner` and returns `U::Inner`.
157    ///
158    /// # Returns
159    ///
160    /// Returns a new `IsNone` value of type `U`, which is either:
161    /// - The result of applying `f` to the inner value, wrapped in `U`, if `self` is not none.
162    /// - The none value of `U`, if `self` is none.
163    #[inline]
164    fn map<F, U: IsNone>(self, f: F) -> U
165    where
166        F: Fn(Self::Inner) -> U::Inner,
167    {
168        self.to_opt()
169            .map(|v| U::from_inner(f(v)))
170            .unwrap_or_else(|| U::none())
171    }
172
173    /// Computes the absolute value of the inner value, if it exists.
174    ///
175    /// This method applies the absolute value function to the inner value of `Self` if it's not none.
176    /// If `Self` is none, it returns the none value.
177    ///
178    /// # Type Constraints
179    ///
180    /// * `Self::Inner`: Must implement the `Number` trait, which provides the `abs()` method.
181    ///
182    /// # Returns
183    ///
184    /// Returns a new `Self` instance containing:
185    /// - The absolute value of the inner value, if `self` is not none.
186    /// - The none value of `Self`, if `self` is none.
187    #[inline]
188    fn vabs(self) -> Self
189    where
190        Self::Inner: Number,
191    {
192        self.map(|v| v.abs())
193    }
194
195    #[inline]
196    /// Compares two values for sorting, treating `None` as the largest value.
197    ///
198    /// This method is designed for sorting `Some` values from smallest to largest,
199    /// with `None` values considered larger than any non-`None` value.
200    ///
201    /// # Arguments
202    ///
203    /// * `self` - The first `IsNone` value to compare.
204    /// * `other` - The second `IsNone` value to compare.
205    ///
206    /// # Returns
207    ///
208    /// Returns an `Ordering` that can be used for sorting:
209    /// - `Ordering::Less` if `self` is less than `other`.
210    /// - `Ordering::Equal` if `self` is equal to `other`.
211    /// - `Ordering::Greater` if `self` is greater than `other` or if `self` is `None`.
212    ///
213    /// # Type Constraints
214    ///
215    /// * `Self::Inner`: Must implement the `PartialOrd` trait.
216    ///
217    /// # Notes
218    ///
219    /// - If both values are `Some`, their inner values are compared using `partial_cmp`.
220    /// - If the inner values can't be compared (e.g., NaN for floats), `None` is considered greater.
221    /// - If both values are `None`, they are considered equal.
222    /// - A `None` value is always considered greater than any `Some` value.
223    fn sort_cmp(&self, other: &Self) -> Ordering
224    where
225        Self::Inner: PartialOrd,
226    {
227        match (self.as_opt(), other.as_opt()) {
228            (Some(va), Some(vb)) => va.partial_cmp(vb).unwrap_or_else(|| {
229                if va.is_none() {
230                    Ordering::Greater
231                } else {
232                    Ordering::Less
233                }
234            }),
235            (None, None) => Ordering::Equal,
236            (None, _) => Ordering::Greater,
237            (_, None) => Ordering::Less,
238        }
239    }
240
241    #[inline]
242    /// Compares two values for reverse sorting, treating `None` as the largest value.
243    ///
244    /// This method is designed for sorting `Some` values from largest to smallest,
245    /// with `None` values considered larger than any non-`None` value.
246    ///
247    /// # Arguments
248    ///
249    /// * `self` - The first `IsNone` value to compare.
250    /// * `other` - The second `IsNone` value to compare.
251    ///
252    /// # Returns
253    ///
254    /// Returns an `Ordering` that can be used for reverse sorting:
255    /// - `Ordering::Less` if `self` is greater than `other`.
256    /// - `Ordering::Equal` if `self` is equal to `other`.
257    /// - `Ordering::Greater` if `self` is less than `other` or if `self` is `None`.
258    ///
259    /// # Type Constraints
260    ///
261    /// * `Self::Inner`: Must implement the `PartialOrd` trait.
262    ///
263    /// # Notes
264    ///
265    /// - If both values are `Some`, their inner values are compared using `partial_cmp` and then reversed.
266    /// - If the inner values can't be compared (e.g., NaN for floats), `None` is considered greater.
267    /// - If both values are `None`, they are considered equal.
268    /// - A `None` value is always considered greater than any `Some` value.
269    fn sort_cmp_rev(&self, other: &Self) -> Ordering
270    where
271        Self::Inner: PartialOrd,
272    {
273        match (self.as_opt(), other.as_opt()) {
274            (Some(va), Some(vb)) => va
275                .partial_cmp(vb)
276                .unwrap_or_else(|| {
277                    if va.is_none() {
278                        Ordering::Less
279                    } else {
280                        Ordering::Greater
281                    }
282                })
283                .reverse(),
284            (None, None) => Ordering::Equal,
285            (None, _) => Ordering::Greater,
286            (_, None) => Ordering::Less,
287        }
288    }
289}
290
291pub trait IntoCast: IsNone<Inner = Self> + Clone + Sized {
292    #[inline]
293    fn into_cast<T: IsNone>(self) -> T::Cast<Self>
294    where
295        T::Inner: Cast<Self::Inner>,
296    {
297        T::inner_cast(self)
298    }
299}
300
301impl<U: IsNone<Inner = U> + Clone> IntoCast for U {}
302
303impl IsNone for f32 {
304    type Inner = f32;
305    type Cast<U: IsNone<Inner = U> + Clone> = U;
306
307    #[inline]
308    #[allow(clippy::eq_op)]
309    fn is_none(&self) -> bool {
310        self != self
311    }
312
313    #[inline]
314    fn none() -> Self {
315        f32::NAN
316    }
317
318    #[inline]
319    fn to_opt(self) -> Option<Self::Inner> {
320        if self.is_none() { None } else { Some(self) }
321    }
322
323    #[inline]
324    fn as_opt(&self) -> Option<&Self::Inner> {
325        if self.is_none() { None } else { Some(self) }
326    }
327
328    #[inline(always)]
329    fn from_inner(inner: Self::Inner) -> Self {
330        inner
331    }
332
333    #[inline]
334    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
335    where
336        Self::Inner: Cast<U::Inner>,
337    {
338        Cast::<U>::cast(inner)
339    }
340
341    #[inline(always)]
342    fn unwrap(self) -> Self::Inner {
343        self
344    }
345
346    #[inline]
347    #[allow(clippy::eq_op)]
348    fn not_none(&self) -> bool {
349        self == self
350    }
351
352    #[inline]
353    fn map<F, U: IsNone>(self, f: F) -> U
354    where
355        F: Fn(Self::Inner) -> U::Inner,
356    {
357        U::from_inner(f(self))
358    }
359}
360
361impl IsNone for f64 {
362    type Inner = f64;
363    type Cast<U: IsNone<Inner = U> + Clone> = U;
364    #[inline]
365    #[allow(clippy::eq_op)]
366    fn is_none(&self) -> bool {
367        self != self
368    }
369
370    #[inline]
371    fn none() -> Self {
372        f64::NAN
373    }
374
375    #[inline]
376    fn to_opt(self) -> Option<Self::Inner> {
377        if self.is_none() { None } else { Some(self) }
378    }
379
380    #[inline]
381    fn as_opt(&self) -> Option<&Self::Inner> {
382        if self.is_none() { None } else { Some(self) }
383    }
384
385    #[inline(always)]
386    fn from_inner(inner: Self::Inner) -> Self {
387        inner
388    }
389
390    #[inline]
391    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
392    where
393        Self::Inner: Cast<U::Inner>,
394    {
395        Cast::<U>::cast(inner)
396    }
397
398    #[inline(always)]
399    fn unwrap(self) -> Self::Inner {
400        self
401    }
402    #[inline]
403    #[allow(clippy::eq_op)]
404    fn not_none(&self) -> bool {
405        self == self
406    }
407
408    #[inline]
409    fn map<F, U: IsNone>(self, f: F) -> U
410    where
411        F: Fn(Self::Inner) -> U::Inner,
412    {
413        U::from_inner(f(self))
414    }
415}
416
417impl<T: IsNone<Inner = T>> IsNone for Option<T> {
418    type Inner = T;
419    type Cast<U: IsNone<Inner = U> + Clone> = Option<U>;
420    #[inline]
421    fn is_none(&self) -> bool {
422        self.is_none()
423    }
424
425    #[inline]
426    fn none() -> Self {
427        None
428    }
429
430    #[inline(always)]
431    fn to_opt(self) -> Option<Self::Inner> {
432        self
433    }
434
435    #[inline]
436    fn as_opt(&self) -> Option<&Self::Inner> {
437        self.as_ref()
438    }
439
440    #[inline]
441    fn from_inner(inner: Self::Inner) -> Self {
442        if inner.is_none() { None } else { Some(inner) }
443    }
444
445    #[inline]
446    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
447    where
448        Self::Inner: Cast<U::Inner>,
449    {
450        if inner.is_none() {
451            None
452        } else {
453            Some(Cast::<U>::cast(inner))
454        }
455    }
456
457    #[inline]
458    fn not_none(&self) -> bool {
459        self.is_some()
460    }
461
462    #[inline]
463    fn map<F, U: IsNone>(self, f: F) -> U
464    where
465        F: Fn(Self::Inner) -> U::Inner,
466    {
467        self.map(|v| U::from_inner(f(v)))
468            .unwrap_or_else(|| U::none())
469    }
470}
471
472macro_rules! impl_not_none {
473    ($($type: ty),*) => {
474        $(
475            impl IsNone for $type {
476                type Inner = $type;
477                type Cast<U: IsNone<Inner=U> + Clone> = U;
478                #[inline]
479                #[allow(clippy::eq_op)]
480                fn is_none(&self) -> bool {
481                    false
482                }
483
484                fn none() -> Self {
485                    panic!("Cannot call none() on a non-float type");
486                }
487
488                #[inline(always)]
489                fn to_opt(self) -> Option<Self::Inner> {
490                    Some(self)
491                }
492
493                #[inline]
494                fn as_opt(&self) -> Option<&Self::Inner> {
495                    Some(self)
496                }
497
498                #[inline(always)]
499                fn from_inner(inner: Self::Inner) -> Self {
500                    inner
501                }
502
503
504                #[inline]
505                fn inner_cast<U: IsNone<Inner=U> + Clone>(inner: U) -> Self::Cast<U>
506                where Self::Inner: Cast<U::Inner>
507                {
508                    Cast::<U>::cast(inner)
509                }
510
511
512                #[inline(always)]
513                fn unwrap(self) -> Self::Inner {
514                    self
515                }
516
517                #[inline]
518                #[allow(clippy::eq_op)]
519                fn not_none(&self) -> bool {
520                    true
521                }
522
523
524                #[inline]
525                fn map<F, U: IsNone>(self, f: F) -> U
526                where
527                    F: Fn(Self::Inner) -> U::Inner
528                {
529                    U::from_inner(f(self))
530                }
531
532                #[inline]
533                /// only for sorting(from smallest to largest)
534                fn sort_cmp(&self, other: &Self) -> Ordering
535                where
536                    Self: PartialOrd,
537                {
538                    self.partial_cmp(&other).unwrap()
539                }
540            }
541        )*
542    };
543}
544
545impl_not_none!(bool, u8, i32, i64, isize, u64, usize);
546
547impl IsNone for String {
548    type Inner = String;
549    type Cast<U: IsNone<Inner = U> + Clone> = U;
550    #[inline]
551    fn is_none(&self) -> bool {
552        self == "None"
553    }
554
555    #[inline]
556    fn none() -> Self {
557        "None".to_string()
558    }
559
560    #[inline]
561    fn to_opt(self) -> Option<Self::Inner> {
562        if self.is_none() { None } else { Some(self) }
563    }
564
565    #[inline]
566    fn as_opt(&self) -> Option<&Self::Inner> {
567        if self.is_none() { None } else { Some(self) }
568    }
569
570    #[inline(always)]
571    fn from_inner(inner: Self::Inner) -> Self {
572        inner
573    }
574
575    #[inline]
576    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
577    where
578        Self::Inner: Cast<U::Inner>,
579    {
580        Cast::<U>::cast(inner)
581    }
582
583    #[inline(always)]
584    fn unwrap(self) -> Self::Inner {
585        self
586    }
587
588    #[inline]
589    fn map<F, U: IsNone>(self, f: F) -> U
590    where
591        F: Fn(Self::Inner) -> U::Inner,
592    {
593        U::from_inner(f(self))
594    }
595}
596
597impl<'a> IsNone for &'a str {
598    type Inner = &'a str;
599    type Cast<U: IsNone<Inner = U> + Clone> = U;
600    #[inline]
601    fn is_none(&self) -> bool {
602        *self == "None"
603    }
604
605    #[inline]
606    fn none() -> Self {
607        "None"
608    }
609
610    #[inline]
611    fn to_opt(self) -> Option<Self::Inner> {
612        if self.is_none() { None } else { Some(self) }
613    }
614
615    #[inline]
616    fn as_opt(&self) -> Option<&Self::Inner> {
617        if self.is_none() { None } else { Some(self) }
618    }
619
620    #[inline(always)]
621    fn from_inner(inner: Self::Inner) -> Self {
622        inner
623    }
624
625    #[inline]
626    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
627    where
628        Self::Inner: Cast<U::Inner>,
629    {
630        Cast::<U>::cast(inner)
631    }
632
633    #[inline(always)]
634    fn unwrap(self) -> Self::Inner {
635        self
636    }
637
638    #[inline]
639    fn map<F, U: IsNone>(self, f: F) -> U
640    where
641        F: Fn(Self::Inner) -> U::Inner,
642    {
643        U::from_inner(f(self))
644    }
645}
646
647#[cfg(feature = "time")]
648impl<Unit: TimeUnitTrait> IsNone for DateTime<Unit> {
649    type Inner = DateTime<Unit>;
650    type Cast<U: IsNone<Inner = U> + Clone> = U;
651    #[inline]
652    fn is_none(&self) -> bool {
653        self.is_nat()
654    }
655
656    #[inline]
657    fn none() -> Self {
658        DateTime::nat()
659    }
660
661    #[inline]
662    fn to_opt(self) -> Option<Self::Inner> {
663        if self.is_nat() { None } else { Some(self) }
664    }
665
666    #[inline]
667    fn as_opt(&self) -> Option<&Self::Inner> {
668        if self.is_none() { None } else { Some(self) }
669    }
670
671    #[inline(always)]
672    fn from_inner(inner: Self::Inner) -> Self {
673        inner
674    }
675
676    #[inline]
677    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
678    where
679        Self::Inner: Cast<U::Inner>,
680    {
681        Cast::<U>::cast(inner)
682    }
683
684    #[inline(always)]
685    fn unwrap(self) -> Self::Inner {
686        self
687    }
688
689    #[inline]
690    fn map<F, U: IsNone>(self, f: F) -> U
691    where
692        F: Fn(Self::Inner) -> U::Inner,
693    {
694        U::from_inner(f(self))
695    }
696}
697
698#[cfg(feature = "time")]
699impl IsNone for TimeDelta {
700    type Inner = TimeDelta;
701    type Cast<U: IsNone<Inner = U> + Clone> = U;
702    #[inline]
703    fn is_none(&self) -> bool {
704        self.is_nat()
705    }
706
707    #[inline]
708    fn none() -> Self {
709        Self::nat()
710    }
711
712    #[inline]
713    fn to_opt(self) -> Option<Self::Inner> {
714        if self.is_none() { None } else { Some(self) }
715    }
716
717    #[inline]
718    fn as_opt(&self) -> Option<&Self::Inner> {
719        if self.is_none() { None } else { Some(self) }
720    }
721
722    #[inline(always)]
723    fn from_inner(inner: Self::Inner) -> Self {
724        inner
725    }
726
727    #[inline]
728    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
729    where
730        Self::Inner: Cast<U::Inner>,
731    {
732        Cast::<U>::cast(inner)
733    }
734
735    #[inline(always)]
736    fn unwrap(self) -> Self::Inner {
737        self
738    }
739
740    #[inline]
741    fn map<F, U: IsNone>(self, f: F) -> U
742    where
743        F: Fn(Self::Inner) -> U::Inner,
744    {
745        U::from_inner(f(self))
746    }
747}
748
749#[cfg(feature = "time")]
750impl IsNone for Time {
751    type Inner = Time;
752    type Cast<U: IsNone<Inner = U> + Clone> = U;
753    #[inline]
754    fn is_none(&self) -> bool {
755        self.is_nat()
756    }
757
758    #[inline]
759    fn none() -> Self {
760        Self::nat()
761    }
762
763    #[inline]
764    fn to_opt(self) -> Option<Self::Inner> {
765        if self.is_none() { None } else { Some(self) }
766    }
767
768    #[inline]
769    fn as_opt(&self) -> Option<&Self::Inner> {
770        if self.is_none() { None } else { Some(self) }
771    }
772
773    #[inline(always)]
774    fn from_inner(inner: Self::Inner) -> Self {
775        inner
776    }
777
778    #[inline]
779    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
780    where
781        Self::Inner: Cast<U::Inner>,
782    {
783        Cast::<U>::cast(inner)
784    }
785
786    #[inline(always)]
787    fn unwrap(self) -> Self::Inner {
788        self
789    }
790
791    #[inline]
792    fn map<F, U: IsNone>(self, f: F) -> U
793    where
794        F: Fn(Self::Inner) -> U::Inner,
795    {
796        U::from_inner(f(self))
797    }
798}
799
800impl<T: Clone> IsNone for Vec<T> {
801    type Inner = Vec<T>;
802    type Cast<U: IsNone<Inner = U>> = U;
803    #[inline]
804    fn is_none(&self) -> bool {
805        self.is_empty()
806    }
807
808    #[inline]
809    fn none() -> Self {
810        Vec::new()
811    }
812
813    #[inline]
814    fn to_opt(self) -> Option<Self::Inner> {
815        if self.is_none() { None } else { Some(self) }
816    }
817
818    #[inline]
819    fn as_opt(&self) -> Option<&Self::Inner> {
820        if self.is_none() { None } else { Some(self) }
821    }
822
823    #[inline(always)]
824    fn from_inner(inner: Self::Inner) -> Self {
825        inner
826    }
827
828    #[inline]
829    fn inner_cast<U: IsNone<Inner = U> + Clone>(inner: U) -> Self::Cast<U>
830    where
831        Self::Inner: Cast<U::Inner>,
832    {
833        Cast::<U>::cast(inner)
834    }
835
836    #[inline(always)]
837    fn unwrap(self) -> Self::Inner {
838        self
839    }
840
841    #[inline]
842    fn map<F, U: IsNone>(self, f: F) -> U
843    where
844        F: Fn(Self::Inner) -> U::Inner,
845    {
846        U::from_inner(f(self))
847    }
848}
849
850#[cfg(test)]
851mod tests {
852    use crate::{Cast, IsNone};
853
854    #[test]
855    fn test_str() {
856        let a = "dsf";
857        assert_eq!(a.unwrap(), "dsf");
858        assert_eq!(a.to_opt(), Some("dsf"));
859        let a = Some("dsf");
860        assert_eq!(a.to_opt(), Some("dsf"));
861    }
862
863    #[test]
864    fn test_type_cast() {
865        fn test1<T: IsNone>(_v: T) -> f64
866        where
867            T::Inner: Cast<f64>,
868        {
869            let out = T::inner_cast(0.);
870            out.unwrap()
871        }
872        assert_eq!(0., test1(2_i32));
873        assert_eq!(0., test1(Some(3_usize)));
874
875        fn test2<T: IsNone>(_v: T) -> T::Cast<f64>
876        where
877            T::Inner: Cast<f64>,
878        {
879            T::inner_cast(0.)
880        }
881        assert_eq!(0., test2(2_i32));
882        assert_eq!(Some(0.), test2(Some(3_usize)));
883
884        fn test3<T: IsNone>(_v: T) -> f64
885        where
886            T::Inner: Cast<f64>,
887        {
888            let out = T::inner_cast(0.);
889            let v = out.unwrap();
890            if v > 1. { v + 1. } else { v + 2. }
891        }
892        assert_eq!(2., test3(1_i32));
893    }
894
895    #[test]
896    fn test_unwrap() {
897        let v = Some(f64::NAN);
898        assert!(v.not_none());
899        assert!(IsNone::unwrap(v).is_nan());
900        let v: Option<i32> = None;
901        assert!(!v.not_none());
902        let v = f64::NAN;
903        assert!(v.is_none());
904        let v = 1;
905        assert!(!v.is_none());
906    }
907}