use super::Client;
use crate::{
error::Error,
shared::IntoArgs,
types::{
MessageEnvelope, Request, RequestId, RequestParamsMeta, Response,
notification::Notification, resource::Uri,
},
};
pub struct BatchBuilder<'a> {
pub(super) client: &'a mut Client,
pub(super) items: Vec<MessageEnvelope>,
}
impl std::fmt::Debug for BatchBuilder<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("BatchBuilder")
.field("items_len", &self.items.len())
.finish_non_exhaustive()
}
}
impl<'a> BatchBuilder<'a> {
#[inline]
pub fn len(&self) -> usize {
self.items.len()
}
#[inline]
pub fn is_empty(&self) -> bool {
self.items.is_empty()
}
pub fn list_tools(mut self) -> Self {
use crate::types::{ListToolsRequestParams, tool::commands};
self.push_request(
commands::LIST,
Some(ListToolsRequestParams { cursor: None }),
);
self
}
pub fn call_tool<Args: IntoArgs>(mut self, name: impl Into<String>, args: Args) -> Self {
use crate::types::{CallToolRequestParams, tool::commands};
let id = self.next_id();
let params = CallToolRequestParams {
name: name.into(),
args: args.into_args(),
meta: Some(RequestParamsMeta::new(&id)),
#[cfg(feature = "tasks")]
task: None,
};
let req = Request::new(Some(id), commands::CALL, Some(params));
self.items.push(MessageEnvelope::Request(req));
self
}
pub fn list_resources(mut self) -> Self {
use crate::types::{ListResourcesRequestParams, resource::commands};
self.push_request(
commands::LIST,
Some(ListResourcesRequestParams { cursor: None }),
);
self
}
pub fn read_resource(mut self, uri: impl Into<Uri>) -> Self {
use crate::types::{ReadResourceRequestParams, resource::commands};
let id = self.next_id();
let params = ReadResourceRequestParams {
uri: uri.into(),
meta: Some(RequestParamsMeta::new(&id)),
#[cfg(feature = "server")]
args: None,
};
let req = Request::new(Some(id), commands::READ, Some(params));
self.items.push(MessageEnvelope::Request(req));
self
}
pub fn list_resource_templates(mut self) -> Self {
use crate::types::{ListResourceTemplatesRequestParams, resource::commands};
self.push_request(
commands::TEMPLATES_LIST,
Some(ListResourceTemplatesRequestParams { cursor: None }),
);
self
}
pub fn list_prompts(mut self) -> Self {
use crate::types::{ListPromptsRequestParams, prompt::commands};
self.push_request(
commands::LIST,
Some(ListPromptsRequestParams { cursor: None }),
);
self
}
pub fn get_prompt<Args: IntoArgs>(mut self, name: impl Into<String>, args: Args) -> Self {
use crate::types::{GetPromptRequestParams, prompt::commands};
let id = self.next_id();
let params = GetPromptRequestParams {
name: name.into(),
meta: Some(RequestParamsMeta::new(&id)),
args: args.into_args(),
};
let req = Request::new(Some(id), commands::GET, Some(params));
self.items.push(MessageEnvelope::Request(req));
self
}
pub fn ping(mut self) -> Self {
self.push_request(crate::commands::PING, None::<()>);
self
}
pub fn notify(mut self, method: impl Into<String>, params: Option<serde_json::Value>) -> Self {
let method = method.into();
let notification = Notification::new(&method, params);
self.items.push(MessageEnvelope::Notification(notification));
self
}
pub async fn send(self) -> Result<Vec<Response>, Error> {
self.client.call_batch(self.items).await
}
fn next_id(&self) -> RequestId {
self.client
.generate_id()
.unwrap_or(RequestId::Number(self.items.len() as i64))
}
fn push_request<T: serde::Serialize>(&mut self, method: &str, params: Option<T>) {
let id = self.next_id();
let req = Request::new(Some(id), method, params);
self.items.push(MessageEnvelope::Request(req));
}
}