1use crate::{
2 protocol::{Protocol, ProtocolBuilder, RequestOptions},
3 transport::Transport,
4 types::{
5 ClientCapabilities, Implementation, InitializeRequest, InitializeResponse,
6 RootCapabilities, LATEST_PROTOCOL_VERSION,
7 },
8};
9
10use anyhow::Result;
11use tracing::debug;
12
13#[derive(Clone)]
14pub struct Client<T: Transport> {
15 protocol: Protocol<T>,
16}
17
18impl<T: Transport> Client<T> {
19 pub fn builder(transport: T) -> ClientBuilder<T> {
20 ClientBuilder::new(transport)
21 }
22
23 pub async fn initialize(&self, client_info: Implementation) -> Result<InitializeResponse> {
24 let request = InitializeRequest {
25 protocol_version: LATEST_PROTOCOL_VERSION.to_string(),
26 capabilities: ClientCapabilities {
27 experimental: Some(serde_json::json!({})),
28 sampling: Some(serde_json::json!({})),
29 roots: Some(RootCapabilities {
30 list_changed: Some(false),
31 }),
32 },
33 client_info,
34 };
35 let response = self
36 .request(
37 "initialize",
38 Some(serde_json::to_value(request)?),
39 RequestOptions::default(),
40 )
41 .await?;
42 let response: InitializeResponse = serde_json::from_value(response)
43 .map_err(|e| anyhow::anyhow!("Failed to parse response: {}", e))?;
44
45 if response.protocol_version != LATEST_PROTOCOL_VERSION {
46 return Err(anyhow::anyhow!(
47 "Unsupported protocol version: {}",
48 response.protocol_version
49 ));
50 }
51
52 debug!(
53 "Initialized with protocol version: {}",
54 response.protocol_version
55 );
56 self.protocol
57 .notify("notifications/initialized", None)
58 .await?;
59 Ok(response)
60 }
61
62 pub async fn request(
63 &self,
64 method: &str,
65 params: Option<serde_json::Value>,
66 options: RequestOptions,
67 ) -> Result<serde_json::Value> {
68 let response = self.protocol.request(method, params, options).await?;
69 response
70 .result
71 .ok_or_else(|| anyhow::anyhow!("Request failed: {:?}", response.error))
72 }
73
74 pub async fn start(&self) -> Result<()> {
75 self.protocol.listen().await
76 }
77}
78
79pub struct ClientBuilder<T: Transport> {
80 protocol: ProtocolBuilder<T>,
81}
82
83impl<T: Transport> ClientBuilder<T> {
84 pub fn new(transport: T) -> Self {
85 Self {
86 protocol: ProtocolBuilder::new(transport),
87 }
88 }
89
90 pub fn build(self) -> Client<T> {
91 Client {
92 protocol: self.protocol.build(),
93 }
94 }
95}