use core::time::Duration;
use zeroize::Zeroizing;
use crate::error::Redacted;
use crate::rt::{MaybeSend, MaybeSync};
#[non_exhaustive]
pub struct HookRequest {
pub procedure: &'static str,
pub headers: Vec<(&'static str, String)>,
pub body: Zeroizing<Vec<u8>>,
pub timeout: Duration,
pub max_response_bytes: usize,
}
impl HookRequest {
#[must_use]
pub fn new(
procedure: &'static str,
headers: Vec<(&'static str, String)>,
body: Vec<u8>,
timeout: Duration,
max_response_bytes: usize,
) -> Self {
Self {
procedure,
headers,
body: Zeroizing::new(body),
timeout,
max_response_bytes,
}
}
}
impl core::fmt::Debug for HookRequest {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("HookRequest")
.field("procedure", &self.procedure)
.field("body_bytes", &self.body.len())
.field("timeout", &self.timeout)
.finish_non_exhaustive()
}
}
#[non_exhaustive]
pub struct HookResponse {
pub status: u16,
pub content_type: Option<String>,
pub body: Vec<u8>,
}
impl HookResponse {
#[must_use]
pub fn new(status: u16, content_type: Option<String>, body: Vec<u8>) -> Self {
Self {
status,
content_type,
body,
}
}
}
impl core::fmt::Debug for HookResponse {
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
f.debug_struct("HookResponse")
.field("status", &self.status)
.field("body_bytes", &self.body.len())
.finish_non_exhaustive()
}
}
#[derive(Debug, Clone, thiserror::Error)]
#[non_exhaustive]
pub enum ChannelError {
#[error("hook call timed out")]
Timeout,
#[error("hook response too large")]
TooLarge,
#[error("hook transport failed")]
Transport(Redacted),
}
pub trait HookChannel: MaybeSend + MaybeSync {
fn audience(&self) -> Option<&str>;
fn isolated(&self) -> bool {
false
}
fn call(
&self,
request: HookRequest,
) -> impl core::future::Future<Output = Result<HookResponse, ChannelError>> + MaybeSend;
}