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
9pub 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 fn is_none(&self) -> bool;
56
57 fn none() -> Self;
67
68 fn to_opt(self) -> Option<Self::Inner>;
78
79 fn as_opt(&self) -> Option<&Self::Inner>;
89
90 fn from_inner(inner: Self::Inner) -> Self;
105
106 fn inner_cast<U: IsNone<Inner = U>>(inner: U) -> Self::Cast<U>
123 where
124 Self::Inner: Cast<U::Inner>;
125
126 #[inline]
127 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 #[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 #[inline]
188 fn vabs(self) -> Self
189 where
190 Self::Inner: Number,
191 {
192 self.map(|v| v.abs())
193 }
194
195 #[inline]
196 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 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 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}