1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
use crate::{
accessor::StatusAccessor,
error::{AsserhttpError, AsserhttpResult},
status::infallible::AnyStatus,
};
/// For assertions on http response status returning an error instead of panicking
#[allow(dead_code)]
pub trait FallibleAsserhttpStatus<T> {
/// Expects response status to be equal
/// * `status` - expected status or asserhttp::Status or closure
///
/// # Example
/// ```no_run
/// # use ureq::OrAnyStatus;
/// use asserhttp::*;
///
/// #[tokio::main]
/// async fn main() {
/// reqwest::blocking::get("http://localhost").try_expect_status(200).unwrap();
/// reqwest::blocking::get("http://localhost").try_expect_status(Status::Ok).unwrap();
/// reqwest::blocking::get("http://localhost").try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
/// reqwest::get("http://localhost").await.try_expect_status(200).unwrap();
/// reqwest::get("http://localhost").await.try_expect_status(Status::Ok).unwrap();
/// reqwest::get("http://localhost").await.try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
///
/// isahc::get("http://localhost").try_expect_status(200).unwrap();
/// isahc::get("http://localhost").try_expect_status(Status::Ok).unwrap();
/// isahc::get("http://localhost").try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
/// isahc::get_async("http://localhost").await.try_expect_status(200).unwrap();
/// isahc::get_async("http://localhost").await.try_expect_status(Status::Ok).unwrap();
/// isahc::get_async("http://localhost").await.try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
///
/// surf::get("http://localhost").await.try_expect_status(200).unwrap();
/// surf::get("http://localhost").await.try_expect_status(Status::Ok).unwrap();
/// surf::get("http://localhost").await.try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
///
/// ureq::get("http://localhost").call().or_any_status().try_expect_status(200).unwrap();
/// ureq::get("http://localhost").call().or_any_status().try_expect_status(Status::Ok).unwrap();
/// ureq::get("http://localhost").call().or_any_status().try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
///
/// hyper::Client::new().get("http://localhost".parse().unwrap()).await.try_expect_status(200).unwrap();
/// hyper::Client::new().get("http://localhost".parse().unwrap()).await.try_expect_status(Status::Ok).unwrap();
/// hyper::Client::new().get("http://localhost".parse().unwrap()).await.try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
///
/// awc::Client::default().get("http://localhost").send().await.try_expect_status(200).unwrap();
/// awc::Client::default().get("http://localhost").send().await.try_expect_status(Status::Ok).unwrap();
/// awc::Client::default().get("http://localhost").send().await.try_expect_status(|s| { assert_eq!(s, 200); Ok(()) }).unwrap();
/// }
/// ```
///
/// # Error
/// * [AsserhttpError::StatusMismatch] when actual status is different from expected one
fn try_expect_status(&mut self, status: impl Into<FallibleAnyStatus>) -> AsserhttpResult<&mut T>;
}
impl<T> FallibleAsserhttpStatus<T> for T
where
T: StatusAccessor,
{
fn try_expect_status(&mut self, status: impl Into<FallibleAnyStatus>) -> AsserhttpResult<&mut T> {
status.into()(self.get_status())?;
Ok(self)
}
}
impl<T, E> FallibleAsserhttpStatus<T> for Result<T, E>
where
T: StatusAccessor,
E: std::fmt::Debug,
{
fn try_expect_status(&mut self, status: impl Into<FallibleAnyStatus>) -> AsserhttpResult<&mut T> {
self.as_mut()
.map_err(|e| AsserhttpError::HttpError(format!("{e:?}")))?
.try_expect_status(status)
}
}
pub struct FallibleAnyStatus(Box<dyn Fn(u16) -> AsserhttpResult<()>>);
impl From<u16> for FallibleAnyStatus {
fn from(expected: u16) -> Self {
Self(Box::new(move |actual| {
if actual != expected {
return Err(AsserhttpError::StatusMismatch { expected, actual });
}
Ok(())
}))
}
}
impl From<crate::Status> for FallibleAnyStatus {
fn from(value: crate::Status) -> Self {
value.to_string().parse::<u16>().map(Self::from).unwrap()
}
}
impl<F: 'static> From<F> for FallibleAnyStatus
where
F: Fn(u16) -> AsserhttpResult<()>,
{
fn from(fun: F) -> Self {
Self(Box::new(fun))
}
}
impl std::ops::Deref for FallibleAnyStatus {
type Target = dyn Fn(u16) -> AsserhttpResult<()>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl From<AnyStatus> for FallibleAnyStatus {
fn from(asserter: AnyStatus) -> Self {
Self(Box::new(move |status| {
asserter(status);
Ok(())
}))
}
}