use std::fmt;
use std::num::{NonZeroU32, NonZeroU64, NonZeroUsize};
use std::sync::Arc;
use std::time::Duration;
use crate::cancel::CancelHandle;
use crate::client::GatewayClient;
use crate::debug::DebugCapture;
use crate::observe::{NullObserver, Observer};
pub(crate) const fn nz_u32(value: u32) -> NonZeroU32 {
match NonZeroU32::new(value) {
Some(non_zero) => non_zero,
None => unreachable!(),
}
}
pub(crate) const fn nz_u64(value: u64) -> NonZeroU64 {
match NonZeroU64::new(value) {
Some(non_zero) => non_zero,
None => unreachable!(),
}
}
pub(crate) const fn nz_usize(value: usize) -> NonZeroUsize {
match NonZeroUsize::new(value) {
Some(non_zero) => non_zero,
None => unreachable!(),
}
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub struct RunLimits {
max_tool_iterations: NonZeroU32,
fanout_concurrency: NonZeroUsize,
max_fanout_items: NonZeroUsize,
max_response_bytes: NonZeroU64,
lua_memory_bytes: NonZeroUsize,
lua_log_events: NonZeroU32,
request_timeout: Duration,
}
impl RunLimits {
#[must_use]
pub fn new() -> RunLimits {
RunLimits {
max_tool_iterations: nz_u32(24),
fanout_concurrency: nz_usize(8),
max_fanout_items: nz_usize(1024),
max_response_bytes: nz_u64(16 * 1024 * 1024),
lua_memory_bytes: nz_usize(64 * 1024 * 1024),
lua_log_events: nz_u32(1024),
request_timeout: Duration::from_secs(120),
}
}
#[must_use]
pub fn max_tool_iterations(mut self, value: NonZeroU32) -> RunLimits {
self.max_tool_iterations = value;
self
}
#[must_use]
pub fn fanout_concurrency(mut self, value: NonZeroUsize) -> RunLimits {
self.fanout_concurrency = value;
self
}
#[must_use]
pub fn max_fanout_items(mut self, value: NonZeroUsize) -> RunLimits {
self.max_fanout_items = value;
self
}
#[must_use]
pub fn max_response_bytes(mut self, value: NonZeroU64) -> RunLimits {
self.max_response_bytes = value;
self
}
#[must_use]
pub fn lua_memory_bytes(mut self, value: NonZeroUsize) -> RunLimits {
self.lua_memory_bytes = value;
self
}
#[must_use]
pub fn lua_log_events(mut self, value: NonZeroU32) -> RunLimits {
self.lua_log_events = value;
self
}
#[must_use]
pub fn request_timeout(mut self, value: Duration) -> RunLimits {
self.request_timeout = value;
self
}
}
impl RunLimits {
#[must_use]
pub fn tool_iterations(&self) -> NonZeroU32 {
self.max_tool_iterations
}
#[must_use]
pub fn fanout(&self) -> NonZeroUsize {
self.fanout_concurrency
}
#[must_use]
pub fn fanout_items(&self) -> NonZeroUsize {
self.max_fanout_items
}
#[must_use]
pub fn response_bytes(&self) -> NonZeroU64 {
self.max_response_bytes
}
#[must_use]
pub fn lua_memory(&self) -> NonZeroUsize {
self.lua_memory_bytes
}
#[must_use]
pub fn lua_logs(&self) -> NonZeroU32 {
self.lua_log_events
}
#[must_use]
pub fn timeout(&self) -> Duration {
self.request_timeout
}
}
impl Default for RunLimits {
fn default() -> RunLimits {
RunLimits::new()
}
}
#[non_exhaustive]
pub struct RunConfig {
pub(crate) execution: String,
pub(crate) observer: Arc<dyn Observer>,
pub(crate) debug: Option<Arc<dyn DebugCapture>>,
pub(crate) client: Option<GatewayClient>,
pub(crate) cancel: Option<CancelHandle>,
pub(crate) limits: RunLimits,
}
impl RunConfig {
#[must_use]
pub fn new(execution: impl Into<String>) -> RunConfig {
RunConfig {
execution: execution.into(),
observer: Arc::new(NullObserver),
debug: None,
client: None,
cancel: None,
limits: RunLimits::new(),
}
}
#[must_use]
pub fn observer(mut self, observer: Arc<dyn Observer>) -> RunConfig {
self.observer = observer;
self
}
#[must_use]
pub fn debug(mut self, debug: Arc<dyn DebugCapture>) -> RunConfig {
self.debug = Some(debug);
self
}
#[must_use]
pub fn client(mut self, client: GatewayClient) -> RunConfig {
self.client = Some(client);
self
}
#[must_use]
pub fn cancel(mut self, handle: CancelHandle) -> RunConfig {
self.cancel = Some(handle);
self
}
#[must_use]
pub fn limits(mut self, limits: RunLimits) -> RunConfig {
self.limits = limits;
self
}
#[must_use]
pub fn execution(&self) -> &str {
&self.execution
}
#[must_use]
pub fn limits_ref(&self) -> &RunLimits {
&self.limits
}
}
impl fmt::Debug for RunConfig {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("RunConfig")
.field("execution", &self.execution)
.field("observer", &"<dyn Observer>")
.field("client", &self.client)
.field("debug", &self.debug.as_ref().map(|_| "<dyn DebugCapture>"))
.field("cancel", &self.cancel.is_some())
.field("limits", &self.limits)
.finish()
}
}