tooltest_core/validation/
listing.rs1use std::fmt;
2use std::future::Future;
3
4use rmcp::model::Tool;
5
6use crate::schema::parse_list_tools;
7use crate::{HttpConfig, SchemaConfig, SchemaError, SessionDriver, SessionError, StdioConfig};
8
9#[derive(Debug)]
11pub enum ListToolsError {
12 Session(SessionError),
14 Schema(SchemaError),
16}
17
18impl fmt::Display for ListToolsError {
19 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
20 match self {
21 ListToolsError::Session(error) => write!(f, "session error: {error:?}"),
22 ListToolsError::Schema(error) => write!(f, "schema error: {error}"),
23 }
24 }
25}
26
27impl std::error::Error for ListToolsError {}
28
29impl From<SessionError> for ListToolsError {
30 fn from(error: SessionError) -> Self {
31 ListToolsError::Session(error)
32 }
33}
34
35impl From<SchemaError> for ListToolsError {
36 fn from(error: SchemaError) -> Self {
37 ListToolsError::Schema(error)
38 }
39}
40
41pub async fn list_tools_http(
43 config: &HttpConfig,
44 schema: &SchemaConfig,
45) -> Result<Vec<Tool>, ListToolsError> {
46 list_tools_with_connector(config.clone(), schema, |config| async move {
47 SessionDriver::connect_http(&config).await
48 })
49 .await
50}
51
52pub async fn list_tools_stdio(
54 config: &StdioConfig,
55 schema: &SchemaConfig,
56) -> Result<Vec<Tool>, ListToolsError> {
57 list_tools_with_connector(config.clone(), schema, |config| async move {
58 SessionDriver::connect_stdio(&config).await
59 })
60 .await
61}
62
63pub async fn list_tools_with_session(
65 session: &SessionDriver,
66 schema: &SchemaConfig,
67) -> Result<Vec<Tool>, ListToolsError> {
68 let tools = session.list_tools().await?;
69 let payload = serde_json::to_value(&rmcp::model::ListToolsResult {
70 tools,
71 next_cursor: None,
72 meta: None,
73 })
74 .expect("list tools serialize");
75 let parsed = parse_list_tools(payload, schema)?;
76 Ok(parsed.tools)
77}
78
79pub(crate) async fn list_tools_with_connector<T, F, Fut>(
80 config: T,
81 schema: &SchemaConfig,
82 connector: F,
83) -> Result<Vec<Tool>, ListToolsError>
84where
85 F: FnOnce(T) -> Fut,
86 Fut: Future<Output = Result<SessionDriver, SessionError>>,
87{
88 let session = connector(config).await?;
89 list_tools_with_session(&session, schema).await
90}