use async_trait::async_trait;
use crate::{
Message,
domain::{
A2AError, ContextId, ListTasksParams, ListTasksResult, Task, TaskId, TaskIdParams,
TaskQueryParams, TaskState, VersionedTask,
},
};
#[async_trait]
pub trait AsyncTaskLifecycle: Send + Sync {
async fn create(&self, id: &TaskId, context_id: &ContextId) -> Result<Task, A2AError>;
async fn get(&self, id: &TaskId, history_length: Option<u32>) -> Result<Task, A2AError>;
async fn update_status(
&self,
id: &TaskId,
state: TaskState,
message: Option<Message>,
) -> Result<Task, A2AError>;
async fn cancel(&self, id: &TaskId) -> Result<Task, A2AError>;
async fn exists(&self, id: &TaskId) -> Result<bool, A2AError>;
}
#[async_trait]
pub trait AsyncTaskQuery: Send + Sync {
async fn list(&self, params: &ListTasksParams) -> Result<ListTasksResult, A2AError>;
}
#[async_trait]
pub trait AsyncTaskVersioning: Send + Sync {
async fn version(&self, id: &TaskId) -> Result<u64, A2AError>;
async fn get_versioned(
&self,
id: &TaskId,
history_length: Option<u32>,
) -> Result<VersionedTask, A2AError>;
async fn update_status_checked(
&self,
id: &TaskId,
expected: u64,
state: TaskState,
message: Option<Message>,
) -> Result<VersionedTask, A2AError>;
}
#[async_trait]
pub trait AsyncTaskLifecycleExt: AsyncTaskLifecycle {
async fn get_validated(&self, params: &TaskQueryParams) -> Result<Task, A2AError> {
let id: TaskId = params.id.parse()?;
if let Some(history_length) = params.history_length {
if history_length > 1000 {
return Err(A2AError::ValidationError {
field: "history_length".to_string(),
message: "History length cannot exceed 1000".to_string(),
});
}
}
self.get(&id, params.history_length).await
}
async fn cancel_validated(&self, params: &TaskIdParams) -> Result<Task, A2AError> {
let id: TaskId = params.id.parse()?;
self.cancel(&id).await
}
}
impl<T: AsyncTaskLifecycle + ?Sized> AsyncTaskLifecycleExt for T {}