use std::sync::Arc;
use tokio::sync::Mutex;
use crate::{tools::ToolError, value::Value};
#[derive(Clone)]
pub struct LazyProxy {
inner: Arc<Mutex<LazyProxyInner>>,
pub tool_name: String,
}
struct LazyProxyInner {
handle: Option<tokio::task::JoinHandle<Result<Value, ToolError>>>,
resolved: Option<Result<Value, ToolError>>,
}
impl LazyProxy {
pub fn new(
handle: tokio::task::JoinHandle<Result<Value, ToolError>>,
tool_name: String,
) -> Self {
Self {
inner: Arc::new(Mutex::new(LazyProxyInner { handle: Some(handle), resolved: None })),
tool_name,
}
}
pub async fn resolve(&self) -> Result<Value, ToolError> {
let mut inner = self.inner.lock().await;
if let Some(ref result) = inner.resolved {
return result.clone();
}
let Some(handle) = inner.handle.take() else {
return Err(ToolError::new("LazyProxy handle already consumed"));
};
let result = match handle.await {
Ok(r) => r,
Err(e) => Err(ToolError::new(format!("task join error: {e}"))),
};
inner.resolved = Some(result.clone());
result
}
pub async fn is_resolved(&self) -> bool {
self.inner.lock().await.resolved.is_some()
}
}
impl std::fmt::Debug for LazyProxy {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "<LazyProxy tool={}>", self.tool_name)
}
}