use std::future::{Future, poll_fn};
use std::task::Poll;
use asupersync::Cx;
use fastmcp_core::McpRequestCancellation;
use super::{ManagedCoreError, ManagedToolError, ToolContract, check_tool_call};
pub(super) async fn await_validity<T>(
cx: &Cx,
cancellation: &McpRequestCancellation,
contract: &ToolContract,
future: impl Future<Output = T>,
) -> Result<T, ManagedToolError> {
let mut invalidated = std::pin::pin!(contract.invalidation.cancelled());
let mut cancelled = std::pin::pin!(cancellation.cancelled());
let mut future = std::pin::pin!(future);
poll_fn(|task| {
check_tool_call(cx, cancellation, contract)?;
if invalidated.as_mut().poll(task).is_ready() {
return Poll::Ready(Err(ManagedToolError::Invalidated));
}
if cancelled.as_mut().poll(task).is_ready() {
return Poll::Ready(Err(ManagedCoreError::Cancelled.into()));
}
let outcome = future.as_mut().poll(task);
check_tool_call(cx, cancellation, contract)?;
outcome.map(Ok)
})
.await
}
#[cfg(test)]
mod tests;