mock_http_connector/handler/with/
report.rs

1use std::{borrow::Cow, collections::HashSet};
2
3use crate::hyper::http::HeaderName;
4
5/// Report if a `with` clause for a case matched with an incoming request
6///
7/// This is used to generate debugging information when no cases match a request.
8#[derive(Debug, Clone)]
9pub enum Report {
10    /// The request is a match
11    Match,
12    /// The request is a mismatch
13    ///
14    /// This can contain a [`HashSet`] of [`Reason`]s to help troubleshoot why the specific case
15    /// didn't match the request.
16    Mismatch(HashSet<Reason>),
17}
18
19impl From<bool> for Report {
20    fn from(value: bool) -> Self {
21        match value {
22            true => Self::Match,
23            false => Self::Mismatch(HashSet::default()),
24        }
25    }
26}
27
28impl From<Vec<Reason>> for Report {
29    fn from(value: Vec<Reason>) -> Self {
30        if value.is_empty() {
31            Self::Match
32        } else {
33            Self::Mismatch(value.into_iter().collect())
34        }
35    }
36}
37
38impl From<Option<Reason>> for Report {
39    fn from(value: Option<Reason>) -> Self {
40        match value {
41            None => Self::Match,
42            Some(reason) => {
43                #[allow(clippy::mutable_key_type)]
44                let mut reasons = HashSet::new();
45                reasons.insert(reason);
46                Self::Mismatch(reasons)
47            }
48        }
49    }
50}
51
52/// Reason for mismatch on a case
53#[derive(Debug, Clone, PartialEq, Eq, Hash)]
54pub enum Reason {
55    /// Mismatch on the request method
56    Method,
57    /// Mismatch on the request URI
58    Uri,
59    /// Mismatch on one header
60    Header(HeaderName),
61    /// Mismatch on the payload body
62    Body,
63}
64
65impl Reason {
66    /// Returns a string representation for the [`Reason`]
67    pub fn as_str(&self) -> Cow<'static, str> {
68        match self {
69            Self::Method => "method".into(),
70            Self::Uri => "uri".into(),
71            Self::Header(name) => format!("header `{name}`").into(),
72            Self::Body => "body".into(),
73        }
74    }
75}