use crate::core::operation::Operation;
use crate::error::Result;
pub(crate) const IDEMPOTENCY_KEY_HEADER: &str = "Idempotency-Key";
#[allow(missing_docs)]
#[derive(Debug)]
pub struct RequestSpec {
pub method: http::Method,
pub path: String,
pub query: Vec<(&'static str, String)>,
pub headers: Vec<(&'static str, String)>,
pub body: Option<Vec<u8>>,
}
impl RequestSpec {
pub fn build<O: Operation>(op: &O) -> Result<Self> {
Ok(RequestSpec {
method: O::METHOD,
path: op.path(),
query: op.query(),
headers: op.headers(),
body: op.body()?,
})
}
pub fn is_mutating(&self) -> bool {
!matches!(
self.method,
http::Method::GET | http::Method::HEAD | http::Method::OPTIONS
)
}
pub fn ensure_idempotency_key(&mut self) {
if self.is_mutating()
&& !self
.headers
.iter()
.any(|(k, _)| k.eq_ignore_ascii_case(IDEMPOTENCY_KEY_HEADER))
{
self.headers
.push((IDEMPOTENCY_KEY_HEADER, uuid::Uuid::new_v4().to_string()));
}
}
}