Skip to main content

asserting/
expectations.rs

1//! Definitions of the expectations that are provided by this crate.
2
3#![allow(missing_docs)]
4#![warn(clippy::return_self_not_must_use)]
5
6use crate::std::marker::PhantomData;
7use crate::std::{string::String, vec::Vec};
8use hashbrown::HashSet;
9#[cfg(feature = "regex")]
10use regex::Regex;
11
12/// Creates a [`Not`] expectation combinator wrapping the given expectation.
13///
14/// # Examples
15///
16/// ```
17/// use asserting::expectations::{not, HasLength, IsEmpty, IsEqualTo, IsNegative, StringContains};
18/// use asserting::prelude::*;
19///
20/// assert_that!(41).expecting(not(IsEqualTo { expected: 42 }));
21/// assert_that!([1, 2, 3]).expecting(not(IsEmpty));
22/// assert_that!(37.9).expecting(not(IsNegative));
23/// assert_that!([1, 2, 3]).expecting(not(HasLength { expected_length: 4 }));
24/// assert_that!("almost").expecting(not(StringContains { expected: "entire" }));
25/// ```
26pub fn not<E>(expectation: E) -> Not<E> {
27    Not(expectation)
28}
29
30/// A combinator expectation that inverts the wrapped expectation.
31///
32/// This combinator can only be used with expectations that implement the
33/// [`Invertible`] trait (additional to the [`Expectation`] trait).
34///
35/// Most of the expectations provided by this crate do implement the
36/// [`Invertible`] trait and thus can be used with the `Not` combinator.
37///
38/// Use the function [`not()`] to construct a `Not` combinator containing the
39/// given expectation.
40///
41/// [`Expectation`]: crate::spec::Expectation
42/// [`Invertible`]: crate::spec::Invertible
43#[must_use]
44pub struct Not<E>(pub E);
45
46/// Creates an [`All`] expectation combinator from a tuple of expectations.
47///
48/// # Examples
49///
50/// ```
51/// use asserting::expectations::{all, IsAtMost, IsPositive};
52/// use asserting::prelude::*;
53///
54/// let custom_expectation = all((IsPositive, IsAtMost { expected: 99 }));
55///
56/// assert_that!(42).expecting(custom_expectation);
57/// ```
58pub fn all<A>(expectations: A) -> All<A::Output>
59where
60    A: IntoRec,
61{
62    All(expectations.into_rec())
63}
64
65/// A combinator expectation that verifies that all containing expectations are
66/// met.
67///
68/// Use the function [`all()`] to construct an `All` combinator for a tuple of
69/// expectations.
70#[must_use]
71pub struct All<E>(pub E);
72
73/// Creates an [`Any`] expectation combinator from a tuple of expectations.
74///
75/// # Examples
76///
77/// ```
78/// use asserting::expectations::{any, not, IsEmpty, StringContains};
79/// use asserting::prelude::*;
80///
81/// let custom_expectation = any((not(IsEmpty), StringContains { expected: "unfugiaty" }));
82///
83/// assert_that!("elit fugiat dolores").expecting(custom_expectation);
84/// ```
85pub fn any<A>(expectations: A) -> Any<A::Output>
86where
87    A: IntoRec,
88{
89    Any(expectations.into_rec())
90}
91
92/// A combinator expectation that verifies that any containing expectation is
93/// met.
94///
95/// Use the function [`any()`] to construct an `Any` combinator for a tuple of
96/// expectations.
97pub struct Any<E>(pub E);
98
99/// Creates a [`Rec`] expectation combinator that wraps the given expectation.
100///
101/// This is a convenience function that is equivalent to `Rec::new()`.
102pub fn rec<E>(expectations: E) -> Rec<E> {
103    Rec::new(expectations)
104}
105
106/// A combinator expectation that memorizes ("records") the result of the
107/// wrapped expectation.
108///
109/// Use the function [`rec()`] to conveniently wrap an expectation into the
110/// `Rec` combinator.
111///
112/// # Examples
113///
114/// ```
115/// use asserting::prelude::*;
116/// use asserting::expectations::{IsNegative, rec};
117/// use asserting::spec::Expectation;
118///
119/// // the result of new `Rec` is neither `success` nor `failure`
120/// let mut expectation = rec(IsNegative);
121/// assert_that!(expectation.is_failure()).is_false();
122/// assert_that!(expectation.is_success()).is_false();
123///
124/// // once the `test` method has been called, the result can be queried at a
125/// // later time.
126/// _ = expectation.test(&-42);  // returns true
127/// assert_that!(expectation.is_success()).is_true();
128/// assert_that!(expectation.is_failure()).is_false();
129///
130/// // once the `test` method has been called, the result can be queried at a
131/// // later time.
132/// _= expectation.test(&42);  // returns false
133/// assert_that!(expectation.is_success()).is_false();
134/// assert_that!(expectation.is_failure()).is_true();
135/// ```
136#[must_use]
137pub struct Rec<E> {
138    pub expectation: E,
139    pub result: Option<bool>,
140}
141
142impl<E> Rec<E> {
143    /// Creates a new ìnstance of `Rec` that wraps the given expectation.
144    pub fn new(expectation: E) -> Self {
145        Self {
146            expectation,
147            result: None,
148        }
149    }
150
151    /// Returns true if the `test` method has been called and the result of the
152    /// wrapped expectation was true ("success") and false otherwise.
153    pub fn is_success(&self) -> bool {
154        self.result.is_some_and(|r| r)
155    }
156
157    /// Returns true if the `test` method has been called and the result of the
158    /// wrapped expectation was false ("failure") and false otherwise.
159    pub fn is_failure(&self) -> bool {
160        self.result.is_some_and(|r| !r)
161    }
162}
163
164/// Trait to convert a type into another type that wraps the contained
165/// expectation(s) into `Rec`(s).
166///
167/// If this type contains multiple expectations like `Vec<E: Expectation>` or
168/// tuples of expectations, each expectation should be wrapped into its own
169/// `Rec`.
170pub trait IntoRec {
171    /// The result type with the expectation(s) wrapped into [`Rec`].
172    type Output;
173
174    /// Wraps an expectation of this type into [`Rec`].
175    ///
176    /// If this type contains multiple expectations like `Vec<E: Expectation` or
177    /// tuples of expectations, each expectation should be wrapped into its own
178    /// [`Rec`].
179    fn into_rec(self) -> Self::Output;
180}
181
182/// Creates a [`Predicate`] expectation from a predicate function.
183///
184/// The failure message will contain a generic description of the expectation.
185/// To specify a custom description for the expectation, use the method [`Predicate::with_message`]
186/// on the newly constructed expectation.
187///
188/// # Examples
189///
190/// ```
191/// use asserting::expectations::satisfies;
192/// use asserting::prelude::*;
193///
194/// fn is_odd(number: &i32) -> bool {
195///     *number & 1 == 1
196/// }
197///
198/// // with a generic description
199/// assert_that!(5).expecting(satisfies(is_odd));
200///
201/// // with a custom description
202/// assert_that!(5).expecting(
203///     satisfies(is_odd).with_message("my number to be odd")
204/// );
205/// ```
206pub fn satisfies<F>(predicate: F) -> Predicate<F> {
207    Predicate {
208        predicate,
209        message: None,
210    }
211}
212
213#[must_use]
214pub struct Predicate<F> {
215    pub predicate: F,
216    pub message: Option<String>,
217}
218
219impl<F> Predicate<F> {
220    /// Sets a custom description of the expectation.
221    pub fn with_message(mut self, message: impl Into<String>) -> Self {
222        self.message = Some(message.into());
223        self
224    }
225}
226
227/// Creates an [`IsTrue`] expectation.
228pub fn is_true() -> IsTrue {
229    IsTrue
230}
231
232#[must_use]
233pub struct IsTrue;
234
235/// Creates a [`IsFalse`] expectation.
236pub fn is_false() -> IsFalse {
237    IsFalse
238}
239
240#[must_use]
241pub struct IsFalse;
242
243/// Creates an [`IsEqualTo`] expectation.
244pub fn is_equal_to<E>(expected: E) -> IsEqualTo<E> {
245    IsEqualTo { expected }
246}
247
248#[must_use]
249pub struct IsEqualTo<E> {
250    pub expected: E,
251}
252
253/// Creates an [`IsSameAs`] expectation.
254pub fn is_same_as<E>(expected: E) -> IsSameAs<E> {
255    IsSameAs { expected }
256}
257
258pub struct IsSameAs<E> {
259    pub expected: E,
260}
261
262/// Creates an [`IsCloseTo`] expectation.
263///
264/// The margin is set to a default value. To define a custom margin, use the
265/// method [`IsCloseTo::within_margin`] on the newly constructed expectation.
266///
267/// # Examples
268///
269/// ```
270/// # #[cfg(not(feature = "float-cmp"))]
271/// # fn main() {}
272/// # #[cfg(feature = "float-cmp")]
273/// # fn main() {
274/// use asserting::expectations::is_close_to;
275/// use asserting::prelude::*;
276///
277/// // using the default margin
278/// assert_that!(-2.453).expecting(is_close_to(-2.453));
279///
280/// // with custom margin
281/// assert_that!(-2.453_f32)
282///     .expecting(is_close_to(-2.453).within_margin((0.001, 4)));
283/// # }
284/// ```
285pub fn is_close_to<E, M>(expected: E) -> IsCloseTo<E, M>
286where
287    M: Default,
288{
289    IsCloseTo {
290        expected,
291        margin: M::default(),
292    }
293}
294
295#[must_use]
296pub struct IsCloseTo<E, M> {
297    pub expected: E,
298    pub margin: M,
299}
300
301impl<E, M> IsCloseTo<E, M>
302where
303    M: Default,
304{
305    #[deprecated = "use the function [`is_close_to`] instead"]
306    pub fn new(expected: E) -> Self {
307        Self {
308            expected,
309            margin: M::default(),
310        }
311    }
312}
313
314impl<E, M> IsCloseTo<E, M> {
315    pub fn within_margin(mut self, margin: impl Into<M>) -> Self {
316        self.margin = margin.into();
317        self
318    }
319}
320
321/// Creates an [`IsLessThan`] expectation.
322pub fn is_less_than<E>(expected: E) -> IsLessThan<E> {
323    IsLessThan { expected }
324}
325
326#[must_use]
327pub struct IsLessThan<E> {
328    pub expected: E,
329}
330
331/// Creates an [`IsAtMost`] expectation.
332pub fn is_at_most<E>(expected: E) -> IsAtMost<E> {
333    IsAtMost { expected }
334}
335
336#[must_use]
337pub struct IsAtMost<E> {
338    pub expected: E,
339}
340
341/// Creates an [`IsGreaterThan`] expectation.
342pub fn is_greater_than<E>(expected: E) -> IsGreaterThan<E> {
343    IsGreaterThan { expected }
344}
345
346#[must_use]
347pub struct IsGreaterThan<E> {
348    pub expected: E,
349}
350
351/// Creates an [`IsAtLeast`] expectation.
352pub fn is_at_least<E>(expected: E) -> IsAtLeast<E> {
353    IsAtLeast { expected }
354}
355
356#[must_use]
357pub struct IsAtLeast<E> {
358    pub expected: E,
359}
360
361/// Creates an [`IsBefore`] expectation.
362pub fn is_before<E>(expected: E) -> IsBefore<E> {
363    IsBefore { expected }
364}
365
366#[must_use]
367pub struct IsBefore<E> {
368    pub expected: E,
369}
370
371/// Creates an [`IsAfter`] expectation.
372pub fn is_after<E>(expected: E) -> IsAfter<E> {
373    IsAfter { expected }
374}
375
376#[must_use]
377pub struct IsAfter<E> {
378    pub expected: E,
379}
380
381/// Creates an [`IsBetween`] expectation.
382pub fn is_between<E>(min: E, max: E) -> IsBetween<E> {
383    IsBetween { min, max }
384}
385
386#[must_use]
387pub struct IsBetween<E> {
388    pub min: E,
389    pub max: E,
390}
391
392/// Creates an [`IsInRange`] expectation.
393pub fn is_in_range<R, E>(expected_range: R) -> IsInRange<R, E> {
394    IsInRange {
395        expected_range,
396        _element_type: PhantomData,
397    }
398}
399
400#[must_use]
401pub struct IsInRange<R, E> {
402    pub expected_range: R,
403    _element_type: PhantomData<E>,
404}
405
406impl<R, E> IsInRange<R, E> {
407    #[deprecated = "use the function [`is_in_range`] instead"]
408    pub fn new(expected_range: R) -> Self {
409        Self {
410            expected_range,
411            _element_type: PhantomData,
412        }
413    }
414}
415
416/// Creates an [`IsNegative`] expectation.
417pub fn is_negative() -> IsNegative {
418    IsNegative
419}
420
421#[must_use]
422pub struct IsNegative;
423
424/// Creates an [`IsPositive`] expectation.
425pub fn is_positive() -> IsPositive {
426    IsPositive
427}
428
429#[must_use]
430pub struct IsPositive;
431
432/// Creates an [`IsZero`] expectation.
433pub fn is_zero() -> IsZero {
434    IsZero
435}
436
437#[must_use]
438pub struct IsZero;
439
440/// Creates an [`IsOne`] expectation.
441pub fn is_one() -> IsOne {
442    IsOne
443}
444
445#[must_use]
446pub struct IsOne;
447
448/// Creates an [`IsFinite`] expectation.
449pub fn is_finite() -> IsFinite {
450    IsFinite
451}
452
453#[must_use]
454pub struct IsFinite;
455
456/// Creates an [`IsInfinite`] expectation.
457pub fn is_infinite() -> IsInfinite {
458    IsInfinite
459}
460
461#[must_use]
462pub struct IsInfinite;
463
464/// Creates an [`IsANumber`] expectation.
465pub fn is_a_number() -> IsANumber {
466    IsANumber
467}
468
469#[must_use]
470pub struct IsANumber;
471
472/// Creates a [`HasPrecisionOf`] expectation.
473pub fn has_precision_of(expected_precision: u64) -> HasPrecisionOf {
474    HasPrecisionOf { expected_precision }
475}
476
477#[must_use]
478pub struct HasPrecisionOf {
479    pub expected_precision: u64,
480}
481
482/// Creates a [`HasScaleOf`] expectation.
483pub fn has_scale_of(expected_scale: i64) -> HasScaleOf {
484    HasScaleOf { expected_scale }
485}
486
487#[must_use]
488pub struct HasScaleOf {
489    pub expected_scale: i64,
490}
491
492/// Creates an [`IsInteger`] expectation.
493pub fn is_integer() -> IsInteger {
494    IsInteger
495}
496
497#[must_use]
498pub struct IsInteger;
499
500/// Creates an [`IsLowerCase`] expectation.
501pub fn is_lower_case() -> IsLowerCase {
502    IsLowerCase
503}
504
505#[must_use]
506pub struct IsLowerCase;
507
508/// Creates an [`IsUpperCase`] expectation.
509pub fn is_upper_case() -> IsUpperCase {
510    IsUpperCase
511}
512
513#[must_use]
514pub struct IsUpperCase;
515
516/// Creates an [`IsAscii`] expectation.
517pub fn is_ascii() -> IsAscii {
518    IsAscii
519}
520
521#[must_use]
522pub struct IsAscii;
523
524/// Creates an [`IsAlphabetic`] expectation.
525pub fn is_alphabetic() -> IsAlphabetic {
526    IsAlphabetic
527}
528
529#[must_use]
530pub struct IsAlphabetic;
531
532/// Creates an [`IsAlphanumeric`] expectation.
533pub fn is_alphanumeric() -> IsAlphanumeric {
534    IsAlphanumeric
535}
536
537#[must_use]
538pub struct IsAlphanumeric;
539
540/// Creates an [`IsControlChar`] expectation.
541pub fn is_control_char() -> IsControlChar {
542    IsControlChar
543}
544
545#[must_use]
546pub struct IsControlChar;
547
548/// Creates an [`IsDigit`] expectation.
549pub fn is_digit(radix: u32) -> IsDigit {
550    IsDigit { radix }
551}
552
553#[must_use]
554pub struct IsDigit {
555    pub radix: u32,
556}
557
558/// Creates an [`IsWhitespace`] expectation.
559pub fn is_whitespace() -> IsWhitespace {
560    IsWhitespace
561}
562
563#[must_use]
564pub struct IsWhitespace;
565
566/// Creates an [`IsSome`] expectation.
567pub fn is_some() -> IsSome {
568    IsSome
569}
570
571#[must_use]
572pub struct IsSome;
573
574/// Creates an [`IsNone`] expectation.
575pub fn is_none() -> IsNone {
576    IsNone
577}
578
579#[must_use]
580pub struct IsNone;
581
582/// Creates a [`HasValue`] expectation.
583pub fn has_value<E>(expected: E) -> HasValue<E> {
584    HasValue { expected }
585}
586
587#[must_use]
588pub struct HasValue<E> {
589    pub expected: E,
590}
591
592/// Creates an [`IsOk`] expectation.
593pub fn is_ok() -> IsOk {
594    IsOk
595}
596
597#[must_use]
598pub struct IsOk;
599
600/// Creates an [`IsErr`] expectation.
601pub fn is_err() -> IsErr {
602    IsErr
603}
604
605#[must_use]
606pub struct IsErr;
607
608/// Creates a [`HasError`] expectation.
609pub fn has_error<E>(expected: E) -> HasError<E> {
610    HasError { expected }
611}
612
613#[must_use]
614pub struct HasError<E> {
615    pub expected: E,
616}
617
618/// Creates an [`ErrorHasSource`] expectation.
619pub fn error_has_source() -> ErrorHasSource {
620    ErrorHasSource
621}
622
623#[must_use]
624pub struct ErrorHasSource;
625
626/// Creates an [`ErrorHasSourceMessage`] expectation.
627pub fn error_has_source_message(
628    expected_source_message: impl Into<String>,
629) -> ErrorHasSourceMessage {
630    ErrorHasSourceMessage {
631        expected_source_message: expected_source_message.into(),
632    }
633}
634
635#[must_use]
636pub struct ErrorHasSourceMessage {
637    pub expected_source_message: String,
638}
639
640/// Creates a [`HasDebugMessage`] expectation.
641pub fn has_debug_message<E>(expected: E) -> HasDebugMessage<E> {
642    HasDebugMessage { expected }
643}
644
645pub struct HasDebugMessage<E> {
646    pub expected: E,
647}
648
649/// Creates a [`HasDisplayMessage`] expectation.
650pub fn has_display_message<E>(expected: E) -> HasDisplayMessage<E> {
651    HasDisplayMessage { expected }
652}
653
654pub struct HasDisplayMessage<E> {
655    pub expected: E,
656}
657
658/// Creates an [`IsEmpty`] expectation.
659pub fn is_empty() -> IsEmpty {
660    IsEmpty
661}
662
663#[must_use]
664pub struct IsEmpty;
665
666/// Creates a [`HasLength`] expectation.
667pub fn has_length<E>(expected_length: E) -> HasLength<E> {
668    HasLength { expected_length }
669}
670
671#[must_use]
672pub struct HasLength<E> {
673    pub expected_length: E,
674}
675
676/// Creates a [`HasLengthInRange`] expectation.
677pub fn has_length_in_range<R, E>(expected_range: R) -> HasLengthInRange<R, E> {
678    HasLengthInRange {
679        expected_range,
680        _element_type: PhantomData,
681    }
682}
683
684#[must_use]
685pub struct HasLengthInRange<R, E> {
686    pub expected_range: R,
687    _element_type: PhantomData<E>,
688}
689
690impl<R, E> HasLengthInRange<R, E> {
691    #[deprecated = "use the function [`has_length_in_range`] instead"]
692    pub fn new(expected_range: R) -> Self {
693        Self {
694            expected_range,
695            _element_type: PhantomData,
696        }
697    }
698}
699
700/// Creates a [`HasLengthLessThan`] expectation.
701pub fn has_length_less_than<E>(expected_length: E) -> HasLengthLessThan<E> {
702    HasLengthLessThan { expected_length }
703}
704
705#[must_use]
706pub struct HasLengthLessThan<E> {
707    pub expected_length: E,
708}
709
710/// Creates a [`HasLengthGreaterThan`] expectation.
711pub fn has_length_greater_than<E>(expected_length: E) -> HasLengthGreaterThan<E> {
712    HasLengthGreaterThan { expected_length }
713}
714
715#[must_use]
716pub struct HasLengthGreaterThan<E> {
717    pub expected_length: E,
718}
719
720/// Creates a [`HasAtMostLength`] expectation.
721pub fn has_at_most_length<E>(expected_length: E) -> HasAtMostLength<E> {
722    HasAtMostLength { expected_length }
723}
724
725#[must_use]
726pub struct HasAtMostLength<E> {
727    pub expected_length: E,
728}
729
730/// Creates a [`HasAtLeastLength`] expectation.
731pub fn has_at_least_length<E>(expected_length: E) -> HasAtLeastLength<E> {
732    HasAtLeastLength { expected_length }
733}
734
735#[must_use]
736pub struct HasAtLeastLength<E> {
737    pub expected_length: E,
738}
739
740/// Creates a [`HasCharCount`] expectation.
741pub fn has_char_count<E>(expected_char_count: E) -> HasCharCount<E> {
742    HasCharCount {
743        expected_char_count,
744    }
745}
746
747#[must_use]
748pub struct HasCharCount<E> {
749    pub expected_char_count: E,
750}
751
752/// Creates a [`HasCharCountInRange`] expectation.
753pub fn has_char_count_in_range<R, E>(expected_range: R) -> HasCharCountInRange<R, E> {
754    HasCharCountInRange {
755        expected_range,
756        _element_type: PhantomData,
757    }
758}
759
760#[must_use]
761pub struct HasCharCountInRange<R, E> {
762    pub expected_range: R,
763    _element_type: PhantomData<E>,
764}
765
766impl<R, E> HasCharCountInRange<R, E> {
767    #[deprecated = "use the function [`has_char_count_in_range`] instead"]
768    pub fn new(expected_range: R) -> Self {
769        Self {
770            expected_range,
771            _element_type: PhantomData,
772        }
773    }
774}
775
776/// Creates a [`HasCharCountLessThan`] expectation.
777pub fn has_char_count_less_than<E>(expected_char_count: E) -> HasCharCountLessThan<E> {
778    HasCharCountLessThan {
779        expected_char_count,
780    }
781}
782
783#[must_use]
784pub struct HasCharCountLessThan<E> {
785    pub expected_char_count: E,
786}
787
788/// Creates a [`HasCharCount`] expectation.
789pub fn has_char_count_greater_than<E>(expected_char_count: E) -> HasCharCountGreaterThan<E> {
790    HasCharCountGreaterThan {
791        expected_char_count,
792    }
793}
794
795#[must_use]
796pub struct HasCharCountGreaterThan<E> {
797    pub expected_char_count: E,
798}
799
800/// Creates a [`HasAtMostCharCount`] expectation.
801pub fn has_at_most_char_count<E>(expected_char_count: E) -> HasAtMostCharCount<E> {
802    HasAtMostCharCount {
803        expected_char_count,
804    }
805}
806
807#[must_use]
808pub struct HasAtMostCharCount<E> {
809    pub expected_char_count: E,
810}
811
812/// Creates a [`HasAtLeastCharCount`] expectation.
813pub fn has_at_least_char_count<E>(expected_char_count: E) -> HasAtLeastCharCount<E> {
814    HasAtLeastCharCount {
815        expected_char_count,
816    }
817}
818
819#[must_use]
820pub struct HasAtLeastCharCount<E> {
821    pub expected_char_count: E,
822}
823
824/// Creates a [`StringContains`] expectation.
825pub fn string_contains<E>(expected: E) -> StringContains<E> {
826    StringContains { expected }
827}
828
829#[must_use]
830pub struct StringContains<E> {
831    pub expected: E,
832}
833
834/// Creates a [`StringContainsAnyOf`] expectation.
835pub fn string_contains_any_of<E>(expected: E) -> StringContainsAnyOf<E> {
836    StringContainsAnyOf { expected }
837}
838
839#[must_use]
840pub struct StringContainsAnyOf<E> {
841    pub expected: E,
842}
843
844/// Creates a [`StringStartWith`] expectation.
845pub fn string_starts_with<E>(expected: E) -> StringStartWith<E> {
846    StringStartWith { expected }
847}
848
849#[must_use]
850pub struct StringStartWith<E> {
851    pub expected: E,
852}
853
854/// Creates a [`StringEndsWith`] expectation.
855pub fn string_ends_with<E>(expected: E) -> StringEndsWith<E> {
856    StringEndsWith { expected }
857}
858
859#[must_use]
860pub struct StringEndsWith<E> {
861    pub expected: E,
862}
863
864/// Creates a [`StringMatches`] expectation.
865///
866/// # Panics
867///
868/// Panics, if the regex pattern is invalid or exceeds the size limit.
869#[cfg(feature = "regex")]
870#[cfg_attr(docsrs, doc(cfg(feature = "regex")))]
871pub fn string_matches(regex_pattern: &str) -> StringMatches<'_> {
872    let regex = Regex::new(regex_pattern)
873        .unwrap_or_else(|err| panic!("failed to match string with regex: {err}"));
874    StringMatches {
875        pattern: regex_pattern,
876        regex,
877    }
878}
879
880#[cfg(feature = "regex")]
881#[cfg_attr(docsrs, doc(cfg(feature = "regex")))]
882#[must_use]
883pub struct StringMatches<'a> {
884    pub pattern: &'a str,
885    pub regex: Regex,
886}
887
888#[cfg(feature = "regex")]
889#[cfg_attr(docsrs, doc(cfg(feature = "regex")))]
890impl<'a> StringMatches<'a> {
891    /// Creates a new `StringMatches`-expectation.
892    ///
893    /// # Panics
894    ///
895    /// Panics, if the regex pattern is invalid or exceeds the size limit.
896    #[deprecated = "use the function [`string_matches`] instead"]
897    pub fn new(regex_pattern: &'a str) -> Self {
898        let regex = Regex::new(regex_pattern)
899            .unwrap_or_else(|err| panic!("failed to match string with regex: {err}"));
900        Self {
901            pattern: regex_pattern,
902            regex,
903        }
904    }
905}
906
907/// Creates an [`IteratorContains`] expectation.
908pub fn iterator_contains<E>(expected: E) -> IteratorContains<E> {
909    IteratorContains { expected }
910}
911
912#[must_use]
913pub struct IteratorContains<E> {
914    pub expected: E,
915}
916
917/// Creates an [`IteratorContainsExactlyInAnyOrder`] expectation.
918pub fn iterator_contains_exactly_in_any_order<E>(
919    expected: impl IntoIterator<Item = E>,
920) -> IteratorContainsExactlyInAnyOrder<E> {
921    IteratorContainsExactlyInAnyOrder {
922        expected: Vec::from_iter(expected),
923        missing: HashSet::new(),
924        extra: HashSet::new(),
925    }
926}
927
928#[must_use]
929pub struct IteratorContainsExactlyInAnyOrder<E> {
930    pub expected: Vec<E>,
931    pub missing: HashSet<usize>,
932    pub extra: HashSet<usize>,
933}
934
935impl<E> IteratorContainsExactlyInAnyOrder<E> {
936    #[deprecated = "use the function [`iterator_contains_exactly_in_any_order`] instead"]
937    pub fn new(expected: Vec<E>) -> Self {
938        Self {
939            expected,
940            missing: HashSet::new(),
941            extra: HashSet::new(),
942        }
943    }
944}
945
946/// Creates an [`IteratorContainsAnyOf`] expectation.
947pub fn iterator_contains_any_of<E>(
948    expected: impl IntoIterator<Item = E>,
949) -> IteratorContainsAnyOf<E> {
950    IteratorContainsAnyOf {
951        expected: Vec::from_iter(expected),
952    }
953}
954
955#[must_use]
956pub struct IteratorContainsAnyOf<E> {
957    pub expected: Vec<E>,
958}
959
960/// Creates an [`IteratorContainsAllOf`] expectation.
961pub fn iterator_contains_all_of<E>(
962    expected: impl IntoIterator<Item = E>,
963) -> IteratorContainsAllOf<E> {
964    IteratorContainsAllOf {
965        expected: Vec::from_iter(expected),
966        missing: HashSet::new(),
967    }
968}
969
970#[must_use]
971pub struct IteratorContainsAllOf<E> {
972    pub expected: Vec<E>,
973    pub missing: HashSet<usize>,
974}
975
976impl<E> IteratorContainsAllOf<E> {
977    #[deprecated = "use the function [`iterator_contains_all_of`] instead"]
978    pub fn new(expected: Vec<E>) -> Self {
979        Self {
980            expected,
981            missing: HashSet::new(),
982        }
983    }
984}
985
986/// Creates an [`IteratorContainsOnly`] expectation.
987pub fn iterator_contains_only<E>(expected: impl IntoIterator<Item = E>) -> IteratorContainsOnly<E> {
988    IteratorContainsOnly {
989        expected: Vec::from_iter(expected),
990        extra: HashSet::new(),
991    }
992}
993
994#[must_use]
995pub struct IteratorContainsOnly<E> {
996    pub expected: Vec<E>,
997    pub extra: HashSet<usize>,
998}
999
1000impl<E> IteratorContainsOnly<E> {
1001    #[deprecated = "use the function [`iterator_contains_only`] instead"]
1002    pub fn new(expected: Vec<E>) -> Self {
1003        Self {
1004            expected,
1005            extra: HashSet::new(),
1006        }
1007    }
1008}
1009
1010/// Creates an [`IteratorContainsOnlyOnce`] expectation.
1011pub fn iterator_contains_only_once<E>(
1012    expected: impl IntoIterator<Item = E>,
1013) -> IteratorContainsOnlyOnce<E> {
1014    IteratorContainsOnlyOnce {
1015        expected: Vec::from_iter(expected),
1016        extra: HashSet::new(),
1017        duplicates: HashSet::new(),
1018    }
1019}
1020
1021#[must_use]
1022pub struct IteratorContainsOnlyOnce<E> {
1023    pub expected: Vec<E>,
1024    pub extra: HashSet<usize>,
1025    pub duplicates: HashSet<usize>,
1026}
1027
1028impl<E> IteratorContainsOnlyOnce<E> {
1029    #[deprecated = "use the function [`iterator_contains_only_once`] instead"]
1030    pub fn new(expected: Vec<E>) -> Self {
1031        Self {
1032            expected,
1033            extra: HashSet::new(),
1034            duplicates: HashSet::new(),
1035        }
1036    }
1037}
1038
1039/// Creates an [`IteratorContainsExactly`] expectation.
1040pub fn iterator_contains_exactly<E>(
1041    expected: impl IntoIterator<Item = E>,
1042) -> IteratorContainsExactly<E> {
1043    IteratorContainsExactly {
1044        expected: Vec::from_iter(expected),
1045        missing: HashSet::new(),
1046        extra: HashSet::new(),
1047        out_of_order: HashSet::new(),
1048    }
1049}
1050
1051#[must_use]
1052pub struct IteratorContainsExactly<E> {
1053    pub expected: Vec<E>,
1054    pub missing: HashSet<usize>,
1055    pub extra: HashSet<usize>,
1056    pub out_of_order: HashSet<usize>,
1057}
1058
1059impl<E> IteratorContainsExactly<E> {
1060    #[deprecated = "use the function [`iterator_contains_exactly`] instead"]
1061    pub fn new(expected: Vec<E>) -> Self {
1062        Self {
1063            expected,
1064            missing: HashSet::new(),
1065            extra: HashSet::new(),
1066            out_of_order: HashSet::new(),
1067        }
1068    }
1069}
1070
1071/// Creates an [`IteratorContainsAnyOf`] expectation.
1072pub fn iterator_contains_sequence<E>(
1073    expected: impl IntoIterator<Item = E>,
1074) -> IteratorContainsSequence<E> {
1075    IteratorContainsSequence {
1076        expected: Vec::from_iter(expected),
1077        missing: HashSet::new(),
1078        extra: HashSet::new(),
1079    }
1080}
1081
1082#[must_use]
1083pub struct IteratorContainsSequence<E> {
1084    pub expected: Vec<E>,
1085    pub missing: HashSet<usize>,
1086    pub extra: HashSet<usize>,
1087}
1088
1089impl<E> IteratorContainsSequence<E> {
1090    #[deprecated = "use the function [`iterator_contains_sequence`] instead"]
1091    pub fn new(expected: Vec<E>) -> Self {
1092        Self {
1093            expected,
1094            missing: HashSet::new(),
1095            extra: HashSet::new(),
1096        }
1097    }
1098}
1099
1100/// Creates an [`IteratorContainsAllInOrder`] expectation.
1101pub fn iterator_contains_all_in_order<E>(
1102    expected: impl IntoIterator<Item = E>,
1103) -> IteratorContainsAllInOrder<E> {
1104    IteratorContainsAllInOrder {
1105        expected: Vec::from_iter(expected),
1106        missing: HashSet::new(),
1107    }
1108}
1109
1110#[must_use]
1111pub struct IteratorContainsAllInOrder<E> {
1112    pub expected: Vec<E>,
1113    pub missing: HashSet<usize>,
1114}
1115
1116impl<E> IteratorContainsAllInOrder<E> {
1117    #[deprecated = "use the function [`iterator_contains_all_in_order`] instead"]
1118    pub fn new(expected: Vec<E>) -> Self {
1119        Self {
1120            expected,
1121            missing: HashSet::new(),
1122        }
1123    }
1124}
1125
1126/// Creates an [`IteratorStartsWith`] expectation.
1127pub fn iterator_starts_with<E>(expected: impl IntoIterator<Item = E>) -> IteratorStartsWith<E> {
1128    IteratorStartsWith {
1129        expected: Vec::from_iter(expected),
1130        missing: HashSet::new(),
1131        extra: HashSet::new(),
1132    }
1133}
1134
1135#[must_use]
1136pub struct IteratorStartsWith<E> {
1137    pub expected: Vec<E>,
1138    pub missing: HashSet<usize>,
1139    pub extra: HashSet<usize>,
1140}
1141
1142impl<E> IteratorStartsWith<E> {
1143    #[deprecated = "use the function [`iterator_starts_with`] instead"]
1144    pub fn new(expected: Vec<E>) -> Self {
1145        Self {
1146            expected,
1147            missing: HashSet::new(),
1148            extra: HashSet::new(),
1149        }
1150    }
1151}
1152
1153/// Creates an [`IteratorEndsWith`] expectation.
1154pub fn iterator_ends_with<E>(expected: impl IntoIterator<Item = E>) -> IteratorEndsWith<E> {
1155    IteratorEndsWith {
1156        expected: Vec::from_iter(expected),
1157        missing: HashSet::new(),
1158        extra: HashSet::new(),
1159    }
1160}
1161
1162#[must_use]
1163pub struct IteratorEndsWith<E> {
1164    pub expected: Vec<E>,
1165    pub missing: HashSet<usize>,
1166    pub extra: HashSet<usize>,
1167}
1168
1169impl<E> IteratorEndsWith<E> {
1170    #[deprecated = "use the function [`iterator_ends_with`] instead"]
1171    pub fn new(expected: Vec<E>) -> Self {
1172        Self {
1173            expected,
1174            missing: HashSet::new(),
1175            extra: HashSet::new(),
1176        }
1177    }
1178}
1179
1180pub fn has_single_element() -> HasSingleElement {
1181    HasSingleElement
1182}
1183
1184#[must_use]
1185pub struct HasSingleElement;
1186
1187pub fn has_at_least_number_of_elements(
1188    expected_number_of_elements: usize,
1189) -> HasAtLeastNumberOfElements {
1190    HasAtLeastNumberOfElements {
1191        expected_number_of_elements,
1192    }
1193}
1194
1195#[must_use]
1196pub struct HasAtLeastNumberOfElements {
1197    pub expected_number_of_elements: usize,
1198}
1199
1200pub fn any_satisfies<P>(predicate: P) -> AnySatisfies<P> {
1201    AnySatisfies { predicate }
1202}
1203
1204#[must_use]
1205pub struct AnySatisfies<P> {
1206    pub predicate: P,
1207}
1208
1209pub fn all_satisfy<P>(predicate: P) -> AllSatisfy<P> {
1210    AllSatisfy {
1211        predicate,
1212        failing: HashSet::new(),
1213    }
1214}
1215
1216#[must_use]
1217pub struct AllSatisfy<P> {
1218    pub predicate: P,
1219    pub failing: HashSet<usize>,
1220}
1221
1222pub fn none_satisfies<P>(predicate: P) -> NoneSatisfies<P> {
1223    NoneSatisfies {
1224        predicate,
1225        failing: HashSet::new(),
1226    }
1227}
1228
1229#[must_use]
1230pub struct NoneSatisfies<P> {
1231    pub predicate: P,
1232    pub failing: HashSet<usize>,
1233}
1234
1235/// Creates a [`MapContainsKey`] expectation.
1236pub fn map_contains_key<E>(expected_key: E) -> MapContainsKey<E> {
1237    MapContainsKey { expected_key }
1238}
1239
1240#[must_use]
1241pub struct MapContainsKey<E> {
1242    pub expected_key: E,
1243}
1244
1245/// Creates a [`MapContainsValue`] expectation.
1246pub fn map_contains_value<E>(expected_value: E) -> MapContainsValue<E> {
1247    MapContainsValue { expected_value }
1248}
1249
1250#[must_use]
1251pub struct MapContainsValue<E> {
1252    pub expected_value: E,
1253}
1254
1255/// Creates a [`MapContainsKeys`] expectation.
1256pub fn map_contains_keys<E>(expected_keys: impl IntoIterator<Item = E>) -> MapContainsKeys<E> {
1257    MapContainsKeys {
1258        expected_keys: Vec::from_iter(expected_keys),
1259        missing: HashSet::new(),
1260    }
1261}
1262
1263#[must_use]
1264pub struct MapContainsKeys<E> {
1265    pub expected_keys: Vec<E>,
1266    pub missing: HashSet<usize>,
1267}
1268
1269impl<E> MapContainsKeys<E> {
1270    #[deprecated = "use the function [`map_contains_keys`] instead"]
1271    pub fn new(expected_keys: impl IntoIterator<Item = E>) -> Self {
1272        Self {
1273            expected_keys: Vec::from_iter(expected_keys),
1274            missing: HashSet::new(),
1275        }
1276    }
1277}
1278
1279/// Creates a [`MapDoesNotContainKeys`] expectation.
1280pub fn map_does_not_contain_keys<E>(
1281    expected_keys: impl IntoIterator<Item = E>,
1282) -> MapDoesNotContainKeys<E> {
1283    MapDoesNotContainKeys {
1284        expected_keys: Vec::from_iter(expected_keys),
1285        extra: HashSet::new(),
1286    }
1287}
1288
1289#[must_use]
1290pub struct MapDoesNotContainKeys<E> {
1291    pub expected_keys: Vec<E>,
1292    pub extra: HashSet<usize>,
1293}
1294
1295impl<E> MapDoesNotContainKeys<E> {
1296    #[deprecated = "use the function [`map_does_not_contain_keys`] instead"]
1297    pub fn new(expected_keys: impl IntoIterator<Item = E>) -> Self {
1298        Self {
1299            expected_keys: Vec::from_iter(expected_keys),
1300            extra: HashSet::new(),
1301        }
1302    }
1303}
1304
1305/// Creates a [`MapContainsValues`] expectation.
1306pub fn map_contains_values<E>(
1307    expected_values: impl IntoIterator<Item = E>,
1308) -> MapContainsValues<E> {
1309    MapContainsValues {
1310        expected_values: Vec::from_iter(expected_values),
1311        missing: HashSet::new(),
1312    }
1313}
1314
1315#[must_use]
1316pub struct MapContainsValues<E> {
1317    pub expected_values: Vec<E>,
1318    pub missing: HashSet<usize>,
1319}
1320
1321impl<E> MapContainsValues<E> {
1322    #[deprecated = "use the function [`map_contains_values`] instead"]
1323    pub fn new(expected_values: impl IntoIterator<Item = E>) -> Self {
1324        Self {
1325            expected_values: Vec::from_iter(expected_values),
1326            missing: HashSet::new(),
1327        }
1328    }
1329}
1330
1331/// Creates a [`MapDoesNotContainValues`] expectation.
1332pub fn map_does_not_contain_values<E>(
1333    expected_values: impl IntoIterator<Item = E>,
1334) -> MapDoesNotContainValues<E> {
1335    MapDoesNotContainValues {
1336        expected_values: Vec::from_iter(expected_values),
1337        extra: HashSet::new(),
1338    }
1339}
1340
1341#[must_use]
1342pub struct MapDoesNotContainValues<E> {
1343    pub expected_values: Vec<E>,
1344    pub extra: HashSet<usize>,
1345}
1346
1347impl<E> MapDoesNotContainValues<E> {
1348    #[deprecated = "use the function [`map_does_not_contain_values`] instead"]
1349    pub fn new(expected_values: impl IntoIterator<Item = E>) -> Self {
1350        Self {
1351            expected_values: Vec::from_iter(expected_values),
1352            extra: HashSet::new(),
1353        }
1354    }
1355}
1356
1357/// Creates a [`MapContainsExactlyKeys`] expectation.
1358pub fn map_contains_exactly_keys<E>(
1359    expected_keys: impl IntoIterator<Item = E>,
1360) -> MapContainsExactlyKeys<E> {
1361    MapContainsExactlyKeys {
1362        expected_keys: Vec::from_iter(expected_keys),
1363        missing: HashSet::new(),
1364        extra: HashSet::new(),
1365    }
1366}
1367
1368#[must_use]
1369pub struct MapContainsExactlyKeys<E> {
1370    pub expected_keys: Vec<E>,
1371    pub missing: HashSet<usize>,
1372    pub extra: HashSet<usize>,
1373}
1374
1375impl<E> MapContainsExactlyKeys<E> {
1376    #[deprecated = "use the function [`map_contains_exactly_keys`] instead"]
1377    pub fn new(expected_keys: impl IntoIterator<Item = E>) -> Self {
1378        Self {
1379            expected_keys: Vec::from_iter(expected_keys),
1380            missing: HashSet::new(),
1381            extra: HashSet::new(),
1382        }
1383    }
1384}
1385
1386/// Creates a [`DoesPanic`] expectation.
1387///
1388/// The panic message is not being asserted. To expect to panic with a specific
1389/// message, use the [`DoesPanic::with_message`] method on the newly constructed
1390/// expectation.
1391///
1392/// # Examples
1393///
1394/// ```
1395/// use asserting::expectations::{does_panic};
1396/// use asserting::prelude::*;
1397///
1398/// // expect to panic with any message
1399/// assert_that_code!(|| {panic!("we have a problem!");})
1400///     .expecting(does_panic());
1401///
1402/// // expect to panic with a specific message
1403/// assert_that_code!(|| {panic!("we have a problem!");})
1404///     .expecting(does_panic().with_message("we have a problem!"));
1405/// ```
1406#[cfg(feature = "panic")]
1407#[cfg_attr(docsrs, doc(cfg(feature = "panic")))]
1408pub fn does_panic() -> DoesPanic {
1409    DoesPanic {
1410        expected_message: None,
1411        actual_message: None,
1412    }
1413}
1414
1415#[cfg(feature = "panic")]
1416#[cfg_attr(docsrs, doc(cfg(feature = "panic")))]
1417#[must_use]
1418pub struct DoesPanic {
1419    pub expected_message: Option<String>,
1420    pub actual_message: Option<String>,
1421}
1422
1423#[cfg(feature = "panic")]
1424impl DoesPanic {
1425    pub fn with_message(mut self, message: impl Into<String>) -> Self {
1426        self.expected_message = Some(message.into());
1427        self
1428    }
1429}
1430
1431/// Creates a [`DoesNotPanic`] expectation.
1432#[cfg(feature = "panic")]
1433#[cfg_attr(docsrs, doc(cfg(feature = "panic")))]
1434pub fn does_not_panic() -> DoesNotPanic {
1435    DoesNotPanic {
1436        actual_message: None,
1437    }
1438}
1439
1440#[cfg(feature = "panic")]
1441#[cfg_attr(docsrs, doc(cfg(feature = "panic")))]
1442#[must_use]
1443pub struct DoesNotPanic {
1444    pub actual_message: Option<Box<dyn std::any::Any + Send>>,
1445}