use std::time::{Duration, Instant};
use crate::{SdkError, SdkResult};
#[derive(Clone, Debug, Default)]
pub struct WaitForStepCompletionOptions {
pub(crate) request_id: String,
pub(crate) maximum_wait_time: Duration,
}
impl WaitForStepCompletionOptions {
pub fn new() -> Self {
Self::default()
}
pub fn request_id(mut self, request_id: impl Into<String>) -> Self {
self.request_id = request_id.into();
self
}
pub fn maximum_wait_time(mut self, maximum_wait_time: Duration) -> Self {
self.maximum_wait_time = maximum_wait_time;
self
}
}
#[derive(Clone, Debug, Default)]
pub struct WaitForAttributeOptions {
pub(crate) request_id: String,
pub(crate) maximum_wait_time: Duration,
}
impl WaitForAttributeOptions {
pub fn new() -> Self {
Self::default()
}
pub fn request_id(mut self, request_id: impl Into<String>) -> Self {
self.request_id = request_id.into();
self
}
pub fn maximum_wait_time(mut self, maximum_wait_time: Duration) -> Self {
self.maximum_wait_time = maximum_wait_time;
self
}
}
pub(crate) struct ClientWaitBudget {
deadline: Option<Instant>,
}
impl ClientWaitBudget {
pub(crate) fn new(maximum_wait_time: Duration) -> SdkResult<Self> {
crate::client::seconds32(maximum_wait_time)?;
Ok(Self {
deadline: (!maximum_wait_time.is_zero()).then(|| Instant::now() + maximum_wait_time),
})
}
pub(crate) fn remaining_seconds(
&self,
operation: &'static str,
flow_id: &str,
) -> SdkResult<i32> {
let Some(deadline) = self.deadline else {
return Ok(0);
};
let remaining = deadline.saturating_duration_since(Instant::now());
if remaining.is_zero() {
return Err(SdkError::wait_handler_timeout(operation, flow_id));
}
let seconds = remaining.as_secs() + u64::from(remaining.subsec_nanos() > 0);
i32::try_from(seconds).map_err(|_| crate::client::invalid("Duration exceeds int32"))
}
}