use cfg_if::cfg_if;
use crate::actions::Action;
use crate::requests::{Request, RequestId};
use std::borrow::Cow;
use std::collections::HashMap;
use std::time::Duration;
use url::Url;
use tracing::{error, instrument};
cfg_if! {
if #[cfg(feature = "json")] {
use crate::error::FeroxFuzzError;
use serde_json;
use serde::{de::DeserializeOwned};
}
}
cfg_if! {
if #[cfg(feature = "async")] {
mod async_response;
pub use self::async_response::AsyncResponse;
}
}
cfg_if! {
if #[cfg(feature = "blocking")] {
mod blocking_response;
pub use self::blocking_response::BlockingResponse;
}
}
pub trait Response {
#[must_use]
fn id(&self) -> RequestId;
#[must_use]
fn url(&self) -> &Url;
#[must_use]
fn status_code(&self) -> u16;
#[must_use]
fn headers(&self) -> &HashMap<String, Vec<u8>>;
#[must_use]
fn body(&self) -> &[u8];
#[must_use]
fn content_length(&self) -> usize;
#[must_use]
fn action(&self) -> Option<&Action>;
#[cfg(feature = "json")]
#[cfg_attr(docsrs, doc(cfg(feature = "json")))]
#[instrument(skip_all, level = "trace")]
fn json<T>(&self) -> Result<T, FeroxFuzzError>
where
T: DeserializeOwned,
{
serde_json::from_slice(self.body()).map_err(|source| {
error!(?source, "could not deserialize response body as JSON");
FeroxFuzzError::JSONParseError { source }
})
}
#[must_use]
fn content(&self) -> Option<&[u8]> {
if self.content_length() > 0 {
Some(self.body())
} else {
None
}
}
#[must_use]
fn text(&self) -> Cow<'_, str> {
String::from_utf8_lossy(self.body())
}
#[must_use]
fn line_count(&self) -> usize;
#[must_use]
fn word_count(&self) -> usize;
#[must_use]
fn method(&self) -> &str;
#[must_use]
fn request(&self) -> &Request;
}
pub trait Timed {
#[must_use]
fn elapsed(&self) -> &Duration;
}