1use crate::assertions::{
5 AssertBoolean, AssertChar, AssertDebugString, AssertDecimalNumber, AssertDisplayString,
6 AssertElements, AssertEmptiness, AssertEquality, AssertErrorHasSource, AssertHasCharCount,
7 AssertHasDebugString, AssertHasDisplayString, AssertHasError, AssertHasErrorMessage,
8 AssertHasLength, AssertHasValue, AssertInRange, AssertInfinity, AssertIteratorContains,
9 AssertIteratorContainsInAnyOrder, AssertIteratorContainsInOrder, AssertMapContainsKey,
10 AssertMapContainsValue, AssertNotANumber, AssertNumericIdentity, AssertOption,
11 AssertOptionValue, AssertOrder, AssertOrderedElements, AssertOrderedElementsRef, AssertResult,
12 AssertResultValue, AssertSameAs, AssertSignum, AssertStringContainsAnyOf, AssertStringPattern,
13};
14use crate::expectations::{
15 error_has_source, error_has_source_message, has_at_least_char_count, has_at_least_length,
16 has_at_least_number_of_elements, has_at_most_char_count, has_at_most_length, has_char_count,
17 has_char_count_greater_than, has_char_count_in_range, has_char_count_less_than,
18 has_debug_string, has_display_string, has_error, has_length, has_length_greater_than,
19 has_length_in_range, has_length_less_than, has_precision_of, has_scale_of, has_value,
20 is_a_number, is_after, is_alphabetic, is_alphanumeric, is_ascii, is_at_least, is_at_most,
21 is_before, is_between, is_control_char, is_digit, is_empty, is_equal_to, is_err, is_false,
22 is_finite, is_greater_than, is_in_range, is_infinite, is_integer, is_less_than, is_lower_case,
23 is_negative, is_none, is_ok, is_one, is_positive, is_same_as, is_some, is_true, is_upper_case,
24 is_whitespace, is_zero, iterator_contains, iterator_contains_all_in_order,
25 iterator_contains_all_of, iterator_contains_any_of, iterator_contains_exactly,
26 iterator_contains_exactly_in_any_order, iterator_contains_only, iterator_contains_only_once,
27 iterator_contains_sequence, iterator_ends_with, iterator_starts_with,
28 map_contains_exactly_keys, map_contains_key, map_contains_keys, map_contains_value,
29 map_contains_values, map_does_not_contain_keys, map_does_not_contain_values, not, satisfies,
30 string_contains, string_contains_any_of, string_ends_with, string_starts_with,
31};
32use crate::properties::{
33 AdditiveIdentityProperty, CharCountProperty, DecimalProperties, DefinedOrderProperty,
34 InfinityProperty, IsEmptyProperty, IsNanProperty, LengthProperty, MapProperties,
35 MultiplicativeIdentityProperty, SignumProperty,
36};
37use crate::spec::{
38 And, AssertFailure, CollectFailures, DiffFormat, DoFail, Expectation, Expecting, Expression,
39 FailingStrategy, GetFailures, GetLocation, Location, PanicOnFail, Satisfies, SoftPanic, Spec,
40};
41use crate::std::borrow::{Cow, ToOwned};
42use crate::std::error::Error;
43use crate::std::fmt::{Debug, Display};
44use crate::std::format;
45use crate::std::ops::RangeBounds;
46use crate::std::slice;
47use crate::std::string::{String, ToString};
48use crate::std::vec::Vec;
49use hashbrown::HashSet;
50
51pub struct DerivedSpec<'a, O, S> {
63 original: O,
64 subject: S,
65 expression: Expression<'a>,
66 diff_format: DiffFormat,
67}
68
69impl<O, S> DerivedSpec<'_, O, S> {
70 pub fn expression(&self) -> &Expression<'_> {
72 &self.expression
73 }
74
75 pub const fn diff_format(&self) -> &DiffFormat {
77 &self.diff_format
78 }
79}
80
81impl<'a, O, S> DerivedSpec<'a, O, S> {
82 #[must_use = "a derived spec does nothing unless an assertion method is called"]
83 pub(crate) fn new(
84 original: O,
85 derived_subject: S,
86 expression: Expression<'a>,
87 diff_format: DiffFormat,
88 ) -> Self {
89 Self {
90 original,
91 subject: derived_subject,
92 expression,
93 diff_format,
94 }
95 }
96
97 #[must_use = "a derived spec does nothing unless an assertion method is called"]
99 pub fn named(mut self, subject_name: impl Into<Cow<'a, str>>) -> Self {
100 self.expression = Expression(subject_name.into());
101 self
102 }
103
104 #[must_use = "a spec does nothing unless an assertion method is called"]
111 pub const fn with_diff_format(mut self, diff_format: DiffFormat) -> Self {
112 self.diff_format = diff_format;
113 self
114 }
115}
116
117impl<'a, O, S> GetLocation<'a> for DerivedSpec<'a, O, S>
118where
119 O: GetLocation<'a>,
120{
121 fn location(&self) -> Option<Location<'a>> {
122 self.original.location()
123 }
124}
125
126impl<O, S> GetFailures for DerivedSpec<'_, O, S>
127where
128 O: GetFailures,
129{
130 fn has_failures(&self) -> bool {
131 self.original.has_failures()
132 }
133
134 fn failures(&self) -> Vec<AssertFailure> {
135 self.original.failures()
136 }
137
138 fn display_failures(&self) -> Vec<String> {
139 self.original.display_failures()
140 }
141}
142
143impl<O, S> DoFail for DerivedSpec<'_, O, S>
144where
145 O: DoFail,
146{
147 fn do_fail_with(&mut self, failures: impl IntoIterator<Item = AssertFailure>) {
148 self.original.do_fail_with(failures);
149 }
150
151 fn do_fail_with_message(&mut self, message: impl Into<String>) {
152 self.original.do_fail_with_message(message);
153 }
154}
155
156impl<O, S> SoftPanic for DerivedSpec<'_, O, S>
157where
158 O: SoftPanic,
159{
160 fn soft_panic(&self) {
161 self.original.soft_panic();
162 }
163}
164
165impl<O, S> And for DerivedSpec<'_, O, S> {
166 type Output = O;
167
168 fn and(self) -> Self::Output {
169 self.original
170 }
171}
172
173impl<'a, O, S> DerivedSpec<'a, O, S> {
174 #[must_use = "a derived spec does nothing unless an assertion method is called"]
301 pub fn extracting_ref<F, B, U>(
302 self,
303 property_name: impl Into<Cow<'a, str>>,
304 extract: F,
305 ) -> DerivedSpec<'a, Self, U>
306 where
307 F: FnOnce(&S) -> &B,
308 B: ToOwned<Owned = U> + ?Sized,
309 {
310 let derived_subject = extract(&self.subject).to_owned();
311 let orig_subject_name = &self.expression;
312 let property_name = property_name.into();
313 let expression = Expression(format!("{orig_subject_name}.{property_name}").into());
314 let diff_format = self.diff_format.clone();
315 DerivedSpec {
316 original: self,
317 subject: derived_subject,
318 expression,
319 diff_format,
320 }
321 }
322
323 #[must_use = "a derived spec does nothing unless an assertion method is called"]
407 pub fn extracting<F, U>(
408 self,
409 property_name: impl Into<Cow<'a, str>>,
410 extract: F,
411 ) -> DerivedSpec<'a, O, U>
412 where
413 F: FnOnce(S) -> U,
414 {
415 let derived_subject = extract(self.subject);
416 let orig_subject_name = &self.expression;
417 let property_name = property_name.into();
418 let expression = Expression(format!("{orig_subject_name}.{property_name}").into());
419 let diff_format = self.diff_format.clone();
420 DerivedSpec {
421 original: self.original,
422 subject: derived_subject,
423 expression,
424 diff_format,
425 }
426 }
427
428 #[must_use = "a derived spec does nothing unless an assertion method is called"]
482 pub fn mapping<F, U>(self, map: F) -> DerivedSpec<'a, O, U>
483 where
484 F: FnOnce(S) -> U,
485 {
486 let mapped = map(self.subject);
487 DerivedSpec {
488 original: self.original,
489 subject: mapped,
490 expression: self.expression,
491 diff_format: self.diff_format,
492 }
493 }
494}
495
496impl<'a, O, I> DerivedSpec<'a, O, I>
497where
498 I: IntoIterator,
499{
500 pub(crate) fn extracting_ref_iter<F, U>(
501 self,
502 property_name: impl Into<Cow<'a, str>>,
503 extract: F,
504 ) -> DerivedSpec<'a, DerivedSpec<'a, O, Vec<<I as IntoIterator>::Item>>, Vec<U>>
505 where
506 for<'b> F: Fn(slice::Iter<'b, <I as IntoIterator>::Item>) -> Vec<U>,
507 {
508 let property_name = Expression(property_name.into());
509 let diff_format = self.diff_format.clone();
510 let orig_spec = self.mapping(Vec::from_iter);
511 let new_subject = extract(orig_spec.subject.iter());
512 DerivedSpec {
513 original: orig_spec,
514 subject: new_subject,
515 expression: property_name,
516 diff_format,
517 }
518 }
519}
520
521impl<O, S> Satisfies<S> for DerivedSpec<'_, O, S>
522where
523 O: DoFail,
524{
525 fn satisfies<P>(self, predicate: P) -> Self
526 where
527 P: Fn(&S) -> bool,
528 {
529 self.expecting(satisfies(predicate))
530 }
531
532 fn satisfies_with_message<P>(self, message: impl Into<String>, predicate: P) -> Self
533 where
534 P: Fn(&S) -> bool,
535 {
536 self.expecting(satisfies(predicate).with_message(message))
537 }
538}
539
540impl<O, S> Expecting<S> for DerivedSpec<'_, O, S>
541where
542 O: DoFail,
543{
544 fn expecting(mut self, mut expectation: impl Expectation<S>) -> Self {
545 if !expectation.test(&self.subject) {
546 let message =
547 expectation.message(&self.expression, &self.subject, false, &self.diff_format);
548 self.do_fail_with_message(message);
549 }
550 self
551 }
552}
553
554impl<O, S, E> AssertEquality<E> for DerivedSpec<'_, O, S>
555where
556 S: PartialEq<E> + Debug,
557 E: Debug,
558 O: DoFail,
559{
560 fn is_equal_to(self, expected: E) -> Self {
561 self.expecting(is_equal_to(expected))
562 }
563
564 fn is_not_equal_to(self, expected: E) -> Self {
565 self.expecting(not(is_equal_to(expected)))
566 }
567}
568
569impl<O, S> AssertSameAs<S> for DerivedSpec<'_, O, S>
570where
571 S: PartialEq + Debug,
572 O: DoFail,
573{
574 fn is_same_as(self, expected: S) -> Self {
575 self.expecting(is_same_as(expected))
576 }
577
578 fn is_not_same_as(self, expected: S) -> Self {
579 self.expecting(not(is_same_as(expected)))
580 }
581}
582
583#[cfg(feature = "float-cmp")]
584mod float_cmp {
585 use super::DerivedSpec;
586 use crate::assertions::{AssertIsCloseToWithDefaultMargin, AssertIsCloseToWithinMargin};
587 use crate::expectations::{is_close_to, not};
588 use crate::spec::{DoFail, Expecting};
589 use float_cmp::{F32Margin, F64Margin};
590
591 impl<O> AssertIsCloseToWithinMargin<f32, F32Margin> for DerivedSpec<'_, O, f32>
592 where
593 O: DoFail,
594 {
595 fn is_close_to_with_margin(self, expected: f32, margin: impl Into<F32Margin>) -> Self {
596 self.expecting(is_close_to(expected).within_margin(margin))
597 }
598
599 fn is_not_close_to_with_margin(self, expected: f32, margin: impl Into<F32Margin>) -> Self {
600 self.expecting(not(is_close_to(expected).within_margin(margin)))
601 }
602 }
603
604 impl<O> AssertIsCloseToWithDefaultMargin<f32> for DerivedSpec<'_, O, f32>
605 where
606 O: DoFail,
607 {
608 fn is_close_to(self, expected: f32) -> Self {
609 self.expecting(is_close_to(expected).within_margin((4. * f32::EPSILON, 4)))
610 }
611
612 fn is_not_close_to(self, expected: f32) -> Self {
613 self.expecting(not(
614 is_close_to(expected).within_margin((4. * f32::EPSILON, 4))
615 ))
616 }
617 }
618
619 impl<O> AssertIsCloseToWithinMargin<f64, F64Margin> for DerivedSpec<'_, O, f64>
620 where
621 O: DoFail,
622 {
623 fn is_close_to_with_margin(self, expected: f64, margin: impl Into<F64Margin>) -> Self {
624 self.expecting(is_close_to(expected).within_margin(margin))
625 }
626
627 fn is_not_close_to_with_margin(self, expected: f64, margin: impl Into<F64Margin>) -> Self {
628 self.expecting(not(is_close_to(expected).within_margin(margin)))
629 }
630 }
631
632 impl<O> AssertIsCloseToWithDefaultMargin<f64> for DerivedSpec<'_, O, f64>
633 where
634 O: DoFail,
635 {
636 fn is_close_to(self, expected: f64) -> Self {
637 self.expecting(is_close_to(expected).within_margin((4. * f64::EPSILON, 4)))
638 }
639
640 fn is_not_close_to(self, expected: f64) -> Self {
641 self.expecting(not(
642 is_close_to(expected).within_margin((4. * f64::EPSILON, 4))
643 ))
644 }
645 }
646}
647
648impl<O, S, E> AssertOrder<E> for DerivedSpec<'_, O, S>
649where
650 S: PartialOrd<E> + Debug,
651 E: Debug,
652 O: DoFail,
653{
654 fn is_less_than(self, expected: E) -> Self {
655 self.expecting(is_less_than(expected))
656 }
657
658 fn is_greater_than(self, expected: E) -> Self {
659 self.expecting(is_greater_than(expected))
660 }
661
662 fn is_at_most(self, expected: E) -> Self {
663 self.expecting(is_at_most(expected))
664 }
665
666 fn is_at_least(self, expected: E) -> Self {
667 self.expecting(is_at_least(expected))
668 }
669
670 fn is_before(self, expected: E) -> Self {
671 self.expecting(is_before(expected))
672 }
673
674 fn is_after(self, expected: E) -> Self {
675 self.expecting(is_after(expected))
676 }
677
678 fn is_between(self, min: E, max: E) -> Self {
679 self.expecting(is_between(min, max))
680 }
681}
682
683impl<O, S, E> AssertInRange<E> for DerivedSpec<'_, O, S>
684where
685 S: PartialOrd<E> + Debug,
686 E: PartialOrd<S> + Debug,
687 O: DoFail,
688{
689 fn is_in_range<R>(self, range: R) -> Self
690 where
691 R: RangeBounds<E> + Debug,
692 {
693 self.expecting(is_in_range(range))
694 }
695
696 fn is_not_in_range<R>(self, range: R) -> Self
697 where
698 R: RangeBounds<E> + Debug,
699 {
700 self.expecting(not(is_in_range(range)))
701 }
702}
703
704impl<O, S> AssertNumericIdentity for DerivedSpec<'_, O, S>
705where
706 S: AdditiveIdentityProperty + MultiplicativeIdentityProperty + PartialEq + Debug,
707 O: DoFail,
708{
709 fn is_zero(self) -> Self {
710 self.expecting(is_zero())
711 }
712
713 fn is_one(self) -> Self {
714 self.expecting(is_one())
715 }
716}
717
718impl<O, S> AssertSignum for DerivedSpec<'_, O, S>
719where
720 S: SignumProperty + Debug,
721 O: DoFail,
722{
723 fn is_negative(self) -> Self {
724 self.expecting(is_negative())
725 }
726
727 fn is_not_negative(self) -> Self {
728 self.expecting(not(is_negative()))
729 }
730
731 fn is_positive(self) -> Self {
732 self.expecting(is_positive())
733 }
734
735 fn is_not_positive(self) -> Self {
736 self.expecting(not(is_positive()))
737 }
738}
739
740impl<O, S> AssertInfinity for DerivedSpec<'_, O, S>
741where
742 S: InfinityProperty + Debug,
743 O: DoFail,
744{
745 fn is_infinite(self) -> Self {
746 self.expecting(is_infinite())
747 }
748
749 fn is_finite(self) -> Self {
750 self.expecting(is_finite())
751 }
752}
753
754impl<O, S> AssertNotANumber for DerivedSpec<'_, O, S>
755where
756 S: IsNanProperty + Debug,
757 O: DoFail,
758{
759 fn is_not_a_number(self) -> Self {
760 self.expecting(not(is_a_number()))
761 }
762
763 fn is_a_number(self) -> Self {
764 self.expecting(is_a_number())
765 }
766}
767
768impl<O, S> AssertDecimalNumber for DerivedSpec<'_, O, S>
769where
770 S: DecimalProperties + Debug,
771 O: DoFail,
772{
773 fn has_scale_of(self, expected_scale: i64) -> Self {
774 self.expecting(has_scale_of(expected_scale))
775 }
776
777 fn has_precision_of(self, expected_precision: u64) -> Self {
778 self.expecting(has_precision_of(expected_precision))
779 }
780
781 fn is_integer(self) -> Self {
782 self.expecting(is_integer())
783 }
784}
785
786impl<O> AssertBoolean for DerivedSpec<'_, O, bool>
787where
788 O: DoFail,
789{
790 fn is_true(self) -> Self {
791 self.expecting(is_true())
792 }
793
794 fn is_false(self) -> Self {
795 self.expecting(is_false())
796 }
797}
798
799impl<O> AssertChar for DerivedSpec<'_, O, char>
800where
801 O: DoFail,
802{
803 fn is_lowercase(self) -> Self {
804 self.expecting(is_lower_case())
805 }
806
807 fn is_uppercase(self) -> Self {
808 self.expecting(is_upper_case())
809 }
810
811 fn is_ascii(self) -> Self {
812 self.expecting(is_ascii())
813 }
814
815 fn is_alphabetic(self) -> Self {
816 self.expecting(is_alphabetic())
817 }
818
819 fn is_alphanumeric(self) -> Self {
820 self.expecting(is_alphanumeric())
821 }
822
823 fn is_control_char(self) -> Self {
824 self.expecting(is_control_char())
825 }
826
827 fn is_digit(self, radix: u32) -> Self {
828 self.expecting(is_digit(radix))
829 }
830
831 fn is_whitespace(self) -> Self {
832 self.expecting(is_whitespace())
833 }
834}
835
836impl<O> AssertChar for DerivedSpec<'_, O, &char>
837where
838 O: DoFail,
839{
840 fn is_lowercase(self) -> Self {
841 self.expecting(is_lower_case())
842 }
843
844 fn is_uppercase(self) -> Self {
845 self.expecting(is_upper_case())
846 }
847
848 fn is_ascii(self) -> Self {
849 self.expecting(is_ascii())
850 }
851
852 fn is_alphabetic(self) -> Self {
853 self.expecting(is_alphabetic())
854 }
855
856 fn is_alphanumeric(self) -> Self {
857 self.expecting(is_alphanumeric())
858 }
859
860 fn is_control_char(self) -> Self {
861 self.expecting(is_control_char())
862 }
863
864 fn is_digit(self, radix: u32) -> Self {
865 self.expecting(is_digit(radix))
866 }
867
868 fn is_whitespace(self) -> Self {
869 self.expecting(is_whitespace())
870 }
871}
872
873impl<O, S> AssertEmptiness for DerivedSpec<'_, O, S>
874where
875 S: IsEmptyProperty + Debug,
876 O: DoFail,
877{
878 fn is_empty(self) -> Self {
879 self.expecting(is_empty())
880 }
881
882 fn is_not_empty(self) -> Self {
883 self.expecting(not(is_empty()))
884 }
885}
886
887impl<O, S> AssertHasLength<usize> for DerivedSpec<'_, O, S>
888where
889 S: LengthProperty + Debug,
890 O: DoFail,
891{
892 fn has_length(self, expected_length: usize) -> Self {
893 self.expecting(has_length(expected_length))
894 }
895
896 fn has_length_in_range<R>(self, expected_range: R) -> Self
897 where
898 R: RangeBounds<usize> + Debug,
899 {
900 self.expecting(has_length_in_range(expected_range))
901 }
902
903 fn has_length_less_than(self, expected_length: usize) -> Self {
904 self.expecting(has_length_less_than(expected_length))
905 }
906
907 fn has_length_greater_than(self, expected_length: usize) -> Self {
908 self.expecting(has_length_greater_than(expected_length))
909 }
910
911 fn has_at_most_length(self, expected_length: usize) -> Self {
912 self.expecting(has_at_most_length(expected_length))
913 }
914
915 fn has_at_least_length(self, expected_length: usize) -> Self {
916 self.expecting(has_at_least_length(expected_length))
917 }
918}
919
920impl<O, S> AssertHasCharCount<usize> for DerivedSpec<'_, O, S>
921where
922 S: CharCountProperty + Debug,
923 O: DoFail,
924{
925 fn has_char_count(self, expected_char_count: usize) -> Self {
926 self.expecting(has_char_count(expected_char_count))
927 }
928
929 fn has_char_count_in_range<U>(self, expected_range: U) -> Self
930 where
931 U: RangeBounds<usize> + Debug,
932 {
933 self.expecting(has_char_count_in_range(expected_range))
934 }
935
936 fn has_char_count_less_than(self, expected_char_count: usize) -> Self {
937 self.expecting(has_char_count_less_than(expected_char_count))
938 }
939
940 fn has_char_count_greater_than(self, expected_char_count: usize) -> Self {
941 self.expecting(has_char_count_greater_than(expected_char_count))
942 }
943
944 fn has_at_most_char_count(self, expected_char_count: usize) -> Self {
945 self.expecting(has_at_most_char_count(expected_char_count))
946 }
947
948 fn has_at_least_char_count(self, expected_char_count: usize) -> Self {
949 self.expecting(has_at_least_char_count(expected_char_count))
950 }
951}
952
953impl<O, S> AssertOption for DerivedSpec<'_, O, Option<S>>
954where
955 S: Debug,
956 O: DoFail,
957{
958 fn is_some(self) -> Self {
959 self.expecting(is_some())
960 }
961
962 fn is_none(self) -> Self {
963 self.expecting(is_none())
964 }
965}
966
967impl<'a, O, T> AssertOptionValue for DerivedSpec<'a, O, Option<T>>
968where
969 O: DoFail,
970{
971 type Some = DerivedSpec<'a, O, T>;
972
973 fn some(self) -> Self::Some {
974 self.mapping(|subject| match subject {
975 None => {
976 panic!("expected the subject to be `Some(_)`, but was `None`")
977 },
978 Some(value) => value,
979 })
980 }
981}
982
983impl<'a, O, T> AssertOptionValue for DerivedSpec<'a, O, &'a Option<T>>
984where
985 T: 'a,
986 O: DoFail,
987{
988 type Some = DerivedSpec<'a, O, &'a T>;
989
990 fn some(self) -> Self::Some {
991 self.mapping(|subject| match subject {
992 None => {
993 panic!("expected the subject to be `Some(_)`, but was `None`")
994 },
995 Some(value) => value,
996 })
997 }
998}
999
1000impl<O, T, E> AssertHasValue<E> for DerivedSpec<'_, O, Option<T>>
1001where
1002 T: PartialEq<E> + Debug,
1003 E: Debug,
1004 O: DoFail,
1005{
1006 fn has_value(self, expected: E) -> Self {
1007 self.expecting(has_value(expected))
1008 }
1009}
1010
1011impl<O, T, E> AssertHasValue<E> for DerivedSpec<'_, O, &Option<T>>
1012where
1013 T: PartialEq<E> + Debug,
1014 E: Debug,
1015 O: DoFail,
1016{
1017 fn has_value(self, expected: E) -> Self {
1018 self.expecting(has_value(expected))
1019 }
1020}
1021
1022impl<O, T, E> AssertResult for DerivedSpec<'_, O, Result<T, E>>
1023where
1024 T: Debug,
1025 E: Debug,
1026 O: DoFail,
1027{
1028 fn is_ok(self) -> Self {
1029 self.expecting(is_ok())
1030 }
1031
1032 fn is_err(self) -> Self {
1033 self.expecting(is_err())
1034 }
1035}
1036
1037impl<O, T, E> AssertResult for DerivedSpec<'_, O, &Result<T, E>>
1038where
1039 T: Debug,
1040 E: Debug,
1041 O: DoFail,
1042{
1043 fn is_ok(self) -> Self {
1044 self.expecting(is_ok())
1045 }
1046
1047 fn is_err(self) -> Self {
1048 self.expecting(is_err())
1049 }
1050}
1051
1052impl<'a, O, T, E> AssertResultValue for DerivedSpec<'a, O, Result<T, E>>
1053where
1054 T: Debug,
1055 E: Debug,
1056 O: DoFail,
1057{
1058 type Ok = DerivedSpec<'a, O, T>;
1059 type Err = DerivedSpec<'a, O, E>;
1060
1061 fn ok(self) -> Self::Ok {
1062 self.mapping(|subject| match subject {
1063 Ok(value) => value,
1064 Err(error) => {
1065 panic!("expected the subject to be `Ok(_)`, but was `Err({error:?})`")
1066 },
1067 })
1068 }
1069
1070 fn err(self) -> Self::Err {
1071 self.mapping(|subject| match subject {
1072 Ok(value) => {
1073 panic!("expected the subject to be `Err(_)`, but was `Ok({value:?})`")
1074 },
1075 Err(error) => error,
1076 })
1077 }
1078}
1079
1080impl<'a, O, T, E> AssertResultValue for DerivedSpec<'a, O, &'a Result<T, E>>
1081where
1082 T: Debug,
1083 E: Debug,
1084 O: DoFail,
1085{
1086 type Ok = DerivedSpec<'a, O, &'a T>;
1087 type Err = DerivedSpec<'a, O, &'a E>;
1088
1089 fn ok(self) -> Self::Ok {
1090 self.mapping(|subject| match subject {
1091 Ok(value) => value,
1092 Err(error) => {
1093 panic!("expected the subject to be `Ok(_)`, but was `Err({error:?})`")
1094 },
1095 })
1096 }
1097
1098 fn err(self) -> Self::Err {
1099 self.mapping(|subject| match subject {
1100 Ok(value) => {
1101 panic!("expected the subject to be `Err(_)`, but was `Ok({value:?})`")
1102 },
1103 Err(error) => error,
1104 })
1105 }
1106}
1107
1108impl<O, T, E, X> AssertHasValue<X> for DerivedSpec<'_, O, Result<T, E>>
1109where
1110 T: PartialEq<X> + Debug,
1111 E: Debug,
1112 X: Debug,
1113 O: DoFail,
1114{
1115 fn has_value(self, expected: X) -> Self {
1116 self.expecting(has_value(expected))
1117 }
1118}
1119
1120impl<O, T, E, X> AssertHasValue<X> for DerivedSpec<'_, O, &Result<T, E>>
1121where
1122 T: PartialEq<X> + Debug,
1123 E: Debug,
1124 X: Debug,
1125 O: DoFail,
1126{
1127 fn has_value(self, expected: X) -> Self {
1128 self.expecting(has_value(expected))
1129 }
1130}
1131
1132impl<O, T, E, X> AssertHasError<X> for DerivedSpec<'_, O, Result<T, E>>
1133where
1134 T: Debug,
1135 E: PartialEq<X> + Debug,
1136 X: Debug,
1137 O: DoFail,
1138{
1139 fn has_error(self, expected: X) -> Self {
1140 self.expecting(has_error(expected))
1141 }
1142}
1143
1144impl<O, T, E, X> AssertHasError<X> for DerivedSpec<'_, O, &Result<T, E>>
1145where
1146 T: Debug,
1147 E: PartialEq<X> + Debug,
1148 X: Debug,
1149 O: DoFail,
1150{
1151 fn has_error(self, expected: X) -> Self {
1152 self.expecting(has_error(expected))
1153 }
1154}
1155
1156impl<'a, O, T, E, X> AssertHasErrorMessage<X> for DerivedSpec<'a, O, Result<T, E>>
1157where
1158 T: Debug,
1159 E: Display,
1160 X: Debug,
1161 String: PartialEq<X>,
1162 O: DoFail,
1163{
1164 type ErrorMessage = DerivedSpec<'a, O, String>;
1165
1166 fn has_error_message(self, expected: X) -> Self::ErrorMessage {
1167 self.mapping(|result| match result {
1168 Ok(value) => panic!("expected the subject to be `Err(_)` with message {expected:?}, but was `Ok({value:?})`"),
1169 Err(error) => error.to_string(),
1170 }).expecting(is_equal_to(expected))
1171 }
1172}
1173
1174impl<'a, O, T, E, X> AssertHasErrorMessage<X> for DerivedSpec<'a, O, &Result<T, E>>
1175where
1176 T: Debug,
1177 E: Display,
1178 X: Debug,
1179 String: PartialEq<X>,
1180 O: DoFail,
1181{
1182 type ErrorMessage = DerivedSpec<'a, O, String>;
1183
1184 fn has_error_message(self, expected: X) -> Self::ErrorMessage {
1185 self.mapping(|result| match result {
1186 Ok(value) => panic!("expected the subject to be `Err(_)` with message {expected:?}, but was `Ok({value:?})`"),
1187 Err(error) => error.to_string(),
1188 }).expecting(is_equal_to(expected))
1189 }
1190}
1191
1192impl<'a, O, S> AssertErrorHasSource for DerivedSpec<'a, O, S>
1193where
1194 S: Error,
1195 O: DoFail,
1196{
1197 type SourceMessage = DerivedSpec<'a, O, Option<String>>;
1198
1199 fn has_no_source(self) -> Self {
1200 self.expecting(not(error_has_source()))
1201 }
1202
1203 fn has_source(self) -> Self {
1204 self.expecting(error_has_source())
1205 }
1206
1207 fn has_source_message(self, expected_source_message: impl Into<String>) -> Self::SourceMessage {
1208 let expected_source_message = expected_source_message.into();
1209 self.expecting(error_has_source_message(expected_source_message))
1210 .mapping(|err| err.source().map(ToString::to_string))
1211 }
1212}
1213
1214impl<O, S, E> AssertHasDebugString<E> for DerivedSpec<'_, O, S>
1215where
1216 S: Debug,
1217 E: AsRef<str>,
1218 O: DoFail,
1219{
1220 fn has_debug_string(self, expected: E) -> Self {
1221 self.expecting(has_debug_string(expected))
1222 }
1223
1224 fn does_not_have_debug_string(self, expected: E) -> Self {
1225 self.expecting(not(has_debug_string(expected)))
1226 }
1227}
1228
1229impl<'a, O, S> AssertDebugString for DerivedSpec<'a, O, S>
1230where
1231 S: Debug,
1232 O: DoFail,
1233{
1234 type DebugString = DerivedSpec<'a, O, String>;
1235
1236 fn debug_string(self) -> Self::DebugString {
1237 let expression_debug_string = format!("{}'s debug string", self.expression);
1238 self.mapping(|subject| format!("{subject:?}"))
1239 .named(expression_debug_string)
1240 }
1241}
1242
1243impl<O, S, E> AssertHasDisplayString<E> for DerivedSpec<'_, O, S>
1244where
1245 S: Display,
1246 E: AsRef<str>,
1247 O: DoFail,
1248{
1249 fn has_display_string(self, expected: E) -> Self {
1250 self.expecting(has_display_string(expected))
1251 }
1252
1253 fn does_not_have_display_string(self, expected: E) -> Self {
1254 self.expecting(not(has_display_string(expected)))
1255 }
1256}
1257
1258impl<'a, O, S> AssertDisplayString for DerivedSpec<'a, O, S>
1259where
1260 S: Display,
1261 O: DoFail,
1262{
1263 type DisplayString = DerivedSpec<'a, O, String>;
1264
1265 fn display_string(self) -> Self::DisplayString {
1266 let expression_display_string = format!("{}'s display string", self.expression);
1267 self.mapping(|subject| subject.to_string())
1268 .named(expression_display_string)
1269 }
1270}
1271
1272impl<'a, O, S> AssertStringPattern<&'a str> for DerivedSpec<'a, O, S>
1273where
1274 S: 'a + AsRef<str> + Debug,
1275 O: DoFail,
1276{
1277 fn contains(self, pattern: &'a str) -> Self {
1278 self.expecting(string_contains(pattern))
1279 }
1280
1281 fn does_not_contain(self, pattern: &'a str) -> Self {
1282 self.expecting(not(string_contains(pattern)))
1283 }
1284
1285 fn starts_with(self, pattern: &'a str) -> Self {
1286 self.expecting(string_starts_with(pattern))
1287 }
1288
1289 fn does_not_start_with(self, pattern: &'a str) -> Self {
1290 self.expecting(not(string_starts_with(pattern)))
1291 }
1292
1293 fn ends_with(self, pattern: &'a str) -> Self {
1294 self.expecting(string_ends_with(pattern))
1295 }
1296
1297 fn does_not_end_with(self, pattern: &'a str) -> Self {
1298 self.expecting(not(string_ends_with(pattern)))
1299 }
1300}
1301
1302impl<'a, O, S> AssertStringPattern<String> for DerivedSpec<'a, O, S>
1303where
1304 S: 'a + AsRef<str> + Debug,
1305 O: DoFail,
1306{
1307 fn contains(self, pattern: String) -> Self {
1308 self.expecting(string_contains(pattern))
1309 }
1310
1311 fn does_not_contain(self, pattern: String) -> Self {
1312 self.expecting(not(string_contains(pattern)))
1313 }
1314
1315 fn starts_with(self, pattern: String) -> Self {
1316 self.expecting(string_starts_with(pattern))
1317 }
1318
1319 fn does_not_start_with(self, pattern: String) -> Self {
1320 self.expecting(not(string_starts_with(pattern)))
1321 }
1322
1323 fn ends_with(self, pattern: String) -> Self {
1324 self.expecting(string_ends_with(pattern))
1325 }
1326
1327 fn does_not_end_with(self, pattern: String) -> Self {
1328 self.expecting(not(string_ends_with(pattern)))
1329 }
1330}
1331
1332impl<'a, O, S> AssertStringPattern<char> for DerivedSpec<'a, O, S>
1333where
1334 S: 'a + AsRef<str> + Debug,
1335 O: DoFail,
1336{
1337 fn contains(self, pattern: char) -> Self {
1338 self.expecting(string_contains(pattern))
1339 }
1340
1341 fn does_not_contain(self, pattern: char) -> Self {
1342 self.expecting(not(string_contains(pattern)))
1343 }
1344
1345 fn starts_with(self, pattern: char) -> Self {
1346 self.expecting(string_starts_with(pattern))
1347 }
1348
1349 fn does_not_start_with(self, pattern: char) -> Self {
1350 self.expecting(not(string_starts_with(pattern)))
1351 }
1352
1353 fn ends_with(self, pattern: char) -> Self {
1354 self.expecting(string_ends_with(pattern))
1355 }
1356
1357 fn does_not_end_with(self, pattern: char) -> Self {
1358 self.expecting(not(string_ends_with(pattern)))
1359 }
1360}
1361
1362impl<'a, O, S> AssertStringContainsAnyOf<&'a [char]> for DerivedSpec<'a, O, S>
1363where
1364 S: 'a + AsRef<str> + Debug,
1365 O: DoFail,
1366{
1367 fn contains_any_of(self, expected: &'a [char]) -> Self {
1368 self.expecting(string_contains_any_of(expected))
1369 }
1370
1371 fn does_not_contain_any_of(self, expected: &'a [char]) -> Self {
1372 self.expecting(not(string_contains_any_of(expected)))
1373 }
1374}
1375
1376impl<'a, O, S, const N: usize> AssertStringContainsAnyOf<[char; N]> for DerivedSpec<'a, O, S>
1377where
1378 S: 'a + AsRef<str> + Debug,
1379 O: DoFail,
1380{
1381 fn contains_any_of(self, expected: [char; N]) -> Self {
1382 self.expecting(string_contains_any_of(expected))
1383 }
1384
1385 fn does_not_contain_any_of(self, expected: [char; N]) -> Self {
1386 self.expecting(not(string_contains_any_of(expected)))
1387 }
1388}
1389
1390impl<'a, O, S, const N: usize> AssertStringContainsAnyOf<&'a [char; N]> for DerivedSpec<'a, O, S>
1391where
1392 S: 'a + AsRef<str> + Debug,
1393 O: DoFail,
1394{
1395 fn contains_any_of(self, expected: &'a [char; N]) -> Self {
1396 self.expecting(string_contains_any_of(expected))
1397 }
1398
1399 fn does_not_contain_any_of(self, expected: &'a [char; N]) -> Self {
1400 self.expecting(not(string_contains_any_of(expected)))
1401 }
1402}
1403
1404#[cfg(feature = "regex")]
1405mod regex {
1406 use crate::assertions::AssertStringMatches;
1407 use crate::derived_spec::DerivedSpec;
1408 use crate::expectations::{not, string_matches};
1409 use crate::spec::{DoFail, Expecting};
1410 use crate::std::fmt::Debug;
1411
1412 impl<O, S> AssertStringMatches for DerivedSpec<'_, O, S>
1413 where
1414 S: AsRef<str> + Debug,
1415 O: DoFail,
1416 {
1417 fn matches(self, regex_pattern: &str) -> Self {
1418 self.expecting(string_matches(regex_pattern))
1419 }
1420
1421 fn does_not_match(self, regex_pattern: &str) -> Self {
1422 self.expecting(not(string_matches(regex_pattern)))
1423 }
1424 }
1425}
1426
1427impl<'a, O, S, T, E> AssertIteratorContains<E> for DerivedSpec<'a, O, S>
1428where
1429 S: IntoIterator<Item = T>,
1430 T: PartialEq<E> + Debug,
1431 E: Debug,
1432 O: DoFail,
1433{
1434 type Sequence = DerivedSpec<'a, O, Vec<T>>;
1435
1436 fn contains(self, element: E) -> Self::Sequence {
1437 self.mapping(Vec::from_iter)
1438 .expecting(iterator_contains(element))
1439 }
1440
1441 fn does_not_contain(self, element: E) -> Self::Sequence {
1442 self.mapping(Vec::from_iter)
1443 .expecting(not(iterator_contains(element)))
1444 }
1445}
1446
1447impl<'a, O, S, T, E> AssertIteratorContainsInAnyOrder<E> for DerivedSpec<'a, O, S>
1448where
1449 S: IntoIterator<Item = T>,
1450 T: PartialEq<<E as IntoIterator>::Item> + Debug,
1451 E: IntoIterator,
1452 <E as IntoIterator>::Item: Debug,
1453 O: DoFail,
1454{
1455 type Sequence = DerivedSpec<'a, O, Vec<T>>;
1456
1457 fn contains_exactly_in_any_order(self, expected: E) -> Self::Sequence {
1458 self.mapping(Vec::from_iter)
1459 .expecting(iterator_contains_exactly_in_any_order(expected))
1460 }
1461
1462 fn contains_any_of(self, expected: E) -> Self::Sequence {
1463 self.mapping(Vec::from_iter)
1464 .expecting(iterator_contains_any_of(expected))
1465 }
1466
1467 fn does_not_contain_any_of(self, expected: E) -> Self::Sequence {
1468 self.mapping(Vec::from_iter)
1469 .expecting(not(iterator_contains_any_of(expected)))
1470 }
1471
1472 fn contains_all_of(self, expected: E) -> Self::Sequence {
1473 self.mapping(Vec::from_iter)
1474 .expecting(iterator_contains_all_of(expected))
1475 }
1476
1477 fn contains_only(self, expected: E) -> Self::Sequence {
1478 self.mapping(Vec::from_iter)
1479 .expecting(iterator_contains_only(expected))
1480 }
1481
1482 fn contains_only_once(self, expected: E) -> Self::Sequence {
1483 self.mapping(Vec::from_iter)
1484 .expecting(iterator_contains_only_once(expected))
1485 }
1486}
1487
1488impl<'a, O, S, T, E> AssertIteratorContainsInOrder<E> for DerivedSpec<'a, O, S>
1489where
1490 S: IntoIterator<Item = T>,
1491 <S as IntoIterator>::IntoIter: DefinedOrderProperty,
1492 E: IntoIterator,
1493 <E as IntoIterator>::IntoIter: DefinedOrderProperty,
1494 <E as IntoIterator>::Item: Debug,
1495 T: PartialEq<<E as IntoIterator>::Item> + Debug,
1496 O: DoFail,
1497{
1498 type Sequence = DerivedSpec<'a, O, Vec<T>>;
1499
1500 fn contains_exactly(self, expected: E) -> Self::Sequence {
1501 self.mapping(Vec::from_iter)
1502 .expecting(iterator_contains_exactly(expected))
1503 }
1504
1505 fn contains_sequence(self, expected: E) -> Self::Sequence {
1506 self.mapping(Vec::from_iter)
1507 .expecting(iterator_contains_sequence(expected))
1508 }
1509
1510 fn contains_all_in_order(self, expected: E) -> Self::Sequence {
1511 self.mapping(Vec::from_iter)
1512 .expecting(iterator_contains_all_in_order(expected))
1513 }
1514
1515 fn starts_with(self, expected: E) -> Self::Sequence {
1516 self.mapping(Vec::from_iter)
1517 .expecting(iterator_starts_with(expected))
1518 }
1519
1520 fn ends_with(self, expected: E) -> Self::Sequence {
1521 self.mapping(Vec::from_iter)
1522 .expecting(iterator_ends_with(expected))
1523 }
1524}
1525
1526impl<O, S, E> AssertMapContainsKey<E> for DerivedSpec<'_, O, S>
1527where
1528 S: MapProperties + Debug,
1529 <S as MapProperties>::Key: PartialEq<E> + Debug,
1530 <S as MapProperties>::Value: Debug,
1531 E: Debug,
1532 O: DoFail,
1533{
1534 fn contains_key(self, expected_key: E) -> Self {
1535 self.expecting(map_contains_key(expected_key))
1536 }
1537
1538 fn does_not_contain_key(self, expected_key: E) -> Self {
1539 self.expecting(not(map_contains_key(expected_key)))
1540 }
1541
1542 fn contains_keys(self, expected_keys: impl IntoIterator<Item = E>) -> Self {
1543 self.expecting(map_contains_keys(expected_keys))
1544 }
1545
1546 fn does_not_contain_keys(self, expected_keys: impl IntoIterator<Item = E>) -> Self {
1547 self.expecting(map_does_not_contain_keys(expected_keys))
1548 }
1549
1550 fn contains_exactly_keys(self, expected_keys: impl IntoIterator<Item = E>) -> Self {
1551 self.expecting(map_contains_exactly_keys(expected_keys))
1552 }
1553}
1554
1555impl<O, S, E> AssertMapContainsValue<E> for DerivedSpec<'_, O, S>
1556where
1557 S: MapProperties + Debug,
1558 <S as MapProperties>::Key: Debug,
1559 <S as MapProperties>::Value: PartialEq<E> + Debug,
1560 E: Debug,
1561 O: DoFail,
1562{
1563 fn contains_value(self, expected_value: E) -> Self {
1564 self.expecting(map_contains_value(expected_value))
1565 }
1566
1567 fn does_not_contain_value(self, expected_value: E) -> Self {
1568 self.expecting(not(map_contains_value(expected_value)))
1569 }
1570
1571 fn contains_values(self, expected_values: impl IntoIterator<Item = E>) -> Self {
1572 self.expecting(map_contains_values(expected_values))
1573 }
1574
1575 fn does_not_contain_values(self, expected_values: impl IntoIterator<Item = E>) -> Self {
1576 self.expecting(map_does_not_contain_values(expected_values))
1577 }
1578}
1579
1580impl<'a, O, S, T> AssertOrderedElements for DerivedSpec<'a, O, S>
1581where
1582 S: IntoIterator<Item = T>,
1583 <S as IntoIterator>::IntoIter: DefinedOrderProperty,
1584 T: Debug,
1585 O: DoFail + GetFailures,
1586{
1587 type SingleElement = DerivedSpec<'a, O, T>;
1588 type MultipleElements = DerivedSpec<'a, O, Vec<T>>;
1589
1590 fn first_element(self) -> Self::SingleElement {
1591 let spec = self
1592 .mapping(Vec::from_iter)
1593 .expecting(has_at_least_number_of_elements(1));
1594 if spec.has_failures() {
1595 PanicOnFail.do_fail_with(&spec.failures());
1596 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1597 }
1598 let orig_subject_name = spec.expression();
1599 let new_subject_name = format!("the first element of {orig_subject_name}");
1600 spec.extracting("", |mut collection| collection.remove(0))
1601 .named(new_subject_name)
1602 }
1603
1604 fn last_element(self) -> Self::SingleElement {
1605 let spec = self
1606 .mapping(Vec::from_iter)
1607 .expecting(has_at_least_number_of_elements(1));
1608 if spec.has_failures() {
1609 PanicOnFail.do_fail_with(&spec.failures());
1610 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1611 }
1612 let orig_subject_name = spec.expression();
1613 let new_subject_name = format!("the last element of {orig_subject_name}");
1614 spec.extracting("", |mut collection| {
1615 collection.pop().unwrap_or_else(|| {
1616 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1617 })
1618 })
1619 .named(new_subject_name)
1620 }
1621
1622 fn nth_element(self, n: usize) -> Self::SingleElement {
1623 let min_len = n + 1;
1624 let spec = self
1625 .mapping(Vec::from_iter)
1626 .expecting(has_at_least_number_of_elements(min_len));
1627 if spec.has_failures() {
1628 PanicOnFail.do_fail_with(&spec.failures());
1629 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1630 }
1631 let orig_subject_name = spec.expression();
1632 let new_subject_name = format!("{orig_subject_name}[{n}]");
1633 spec.extracting("", |mut collection| collection.remove(n))
1634 .named(new_subject_name)
1635 }
1636
1637 fn elements_at(self, indices: impl IntoIterator<Item = usize>) -> Self::MultipleElements {
1638 let indices = Vec::from_iter(indices);
1639 let orig_subject_name = self.expression();
1640 let new_subject_name = format!("{orig_subject_name} at positions {indices:?}");
1641 let indices = HashSet::<_>::from_iter(indices);
1642 self.mapping(|subject| {
1643 subject
1644 .into_iter()
1645 .enumerate()
1646 .filter_map(|(i, v)| if indices.contains(&i) { Some(v) } else { None })
1647 .collect()
1648 })
1649 .named(new_subject_name)
1650 }
1651}
1652
1653impl<'a, O, I> AssertElements<'a, I> for DerivedSpec<'a, O, I>
1654where
1655 I: 'a + IntoIterator,
1656 O: DoFail + GetLocation<'a>,
1657{
1658 type Output = DerivedSpec<'a, O, ()>;
1659
1660 fn each_element<A, B>(mut self, assert: A) -> Self::Output
1661 where
1662 A: Fn(Spec<'a, <I as IntoIterator>::Item, CollectFailures>) -> B,
1663 B: GetFailures,
1664 {
1665 let root_expression = &self.expression;
1666 let diff_format = self.diff_format().clone();
1667 let location = self.location();
1668 let mut collected_failures = Vec::new();
1669 let mut position = -1;
1670 for item in self.subject {
1671 position += 1;
1672 let mut element_spec = Spec::new(item, CollectFailures)
1673 .named(format!("{root_expression}[{position}]"))
1674 .with_diff_format(diff_format.clone());
1675 if let Some(location) = location {
1676 element_spec = element_spec.located_at(location);
1677 }
1678 let failures = assert(element_spec).failures();
1679 collected_failures.extend(failures);
1680 }
1681 if !collected_failures.is_empty() {
1682 self.original.do_fail_with(collected_failures);
1683 }
1684 DerivedSpec {
1685 original: self.original,
1686 subject: (),
1687 expression: self.expression,
1688 diff_format: self.diff_format,
1689 }
1690 }
1691
1692 fn any_element<A, B>(mut self, assert: A) -> Self::Output
1693 where
1694 A: Fn(Spec<'a, <I as IntoIterator>::Item, CollectFailures>) -> B,
1695 B: GetFailures,
1696 {
1697 let root_expression = &self.expression;
1698 let diff_format = self.diff_format().clone();
1699 let location = self.location();
1700 let mut collected_failures = Vec::new();
1701 let mut any_success = false;
1702 let mut position = -1;
1703 for item in self.subject {
1704 position += 1;
1705 let mut element_spec = Spec::new(item, CollectFailures)
1706 .named(format!("{root_expression}[{position}]"))
1707 .with_diff_format(diff_format.clone());
1708 if let Some(location) = location {
1709 element_spec = element_spec.located_at(location);
1710 }
1711 let failures = assert(element_spec).failures();
1712 if failures.is_empty() {
1713 any_success = true;
1714 break;
1715 }
1716 collected_failures.extend(failures);
1717 }
1718 if !any_success {
1719 self.original.do_fail_with(collected_failures);
1720 }
1721 DerivedSpec {
1722 original: self.original,
1723 subject: (),
1724 expression: self.expression,
1725 diff_format: self.diff_format,
1726 }
1727 }
1728}
1729
1730impl<'a, O, S, T, U> AssertOrderedElementsRef for DerivedSpec<'a, O, S>
1731where
1732 S: IntoIterator<Item = T>,
1733 <S as IntoIterator>::IntoIter: DefinedOrderProperty,
1734 T: ToOwned<Owned = U> + Debug,
1735 O: DoFail + GetFailures,
1736{
1737 type SingleElement = DerivedSpec<'a, DerivedSpec<'a, O, Vec<T>>, U>;
1738 type MultipleElements = DerivedSpec<'a, DerivedSpec<'a, O, Vec<T>>, Vec<U>>;
1739
1740 fn first_element_ref(self) -> Self::SingleElement {
1741 let original_spec = self
1742 .mapping(Vec::from_iter)
1743 .expecting(has_at_least_number_of_elements(1));
1744 if original_spec.has_failures() {
1745 PanicOnFail.do_fail_with(&original_spec.failures());
1746 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1747 }
1748 let orig_subject_name = original_spec.expression();
1749 let new_subject_name = format!("the first element of {orig_subject_name}");
1750 original_spec.extracting_ref("", |collection|
1751 collection.first()
1752 .unwrap_or_else(||
1753 unreachable!("We should have asserted before, that there is at least one element in the collection/iterator. Please file a bug.")
1754 )
1755 ).named(new_subject_name)
1756 }
1757
1758 fn last_element_ref(self) -> Self::SingleElement {
1759 let original_spec = self
1760 .mapping(Vec::from_iter)
1761 .expecting(has_at_least_number_of_elements(1));
1762 if original_spec.has_failures() {
1763 PanicOnFail.do_fail_with(&original_spec.failures());
1764 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1765 }
1766 let orig_subject_name = original_spec.expression();
1767 let new_subject_name = format!("the last element of {orig_subject_name}");
1768 original_spec.extracting_ref("", |collection|
1769 collection.last()
1770 .unwrap_or_else(||
1771 unreachable!("We should have asserted before, that there is at least one element in the collection/iterator. Please file a bug.")
1772 )
1773 ).named(new_subject_name)
1774 }
1775
1776 fn nth_element_ref(self, n: usize) -> Self::SingleElement {
1777 let min_len = n + 1;
1778 let original_spec = self
1779 .mapping(Vec::from_iter)
1780 .expecting(has_at_least_number_of_elements(min_len));
1781 if original_spec.has_failures() {
1782 PanicOnFail.do_fail_with(&original_spec.failures());
1783 unreachable!("Assertion failed and should have panicked! Please report a bug.")
1784 }
1785 let orig_subject_name = original_spec.expression();
1786 let new_subject_name = format!("{orig_subject_name}[{n}]");
1787 original_spec.extracting_ref("", |collection|
1788 collection.get(n)
1789 .unwrap_or_else(||
1790 unreachable!("We should have asserted before, that there is at least one element in the collection/iterator. Please file a bug.")
1791 )
1792 ).named(new_subject_name)
1793 }
1794
1795 fn elements_ref_at(self, indices: impl IntoIterator<Item = usize>) -> Self::MultipleElements {
1796 let indices = Vec::from_iter(indices);
1797 let orig_subject_name = self.expression();
1798 let new_subject_name = format!("{orig_subject_name} at positions {indices:?}");
1799 let indices = HashSet::<_>::from_iter(indices);
1800 let original_spec = self.mapping(Vec::from_iter);
1801 original_spec
1802 .extracting_ref_iter("", |collection| {
1803 collection
1804 .enumerate()
1805 .filter_map(|(i, e)| {
1806 if indices.contains(&i) {
1807 Some(e.to_owned())
1808 } else {
1809 None
1810 }
1811 })
1812 .collect()
1813 })
1814 .named(new_subject_name)
1815 }
1816}
1817
1818#[cfg(test)]
1819mod tests;