rmcp/model/
serde_impl.rs

1use std::borrow::Cow;
2
3use serde::{Deserialize, Serialize};
4
5use super::{
6    CustomNotification, CustomRequest, Extensions, Meta, Notification, NotificationNoParam,
7    Request, RequestNoParam, RequestOptionalParam,
8};
9#[derive(Serialize, Deserialize)]
10struct WithMeta<'a, P> {
11    #[serde(skip_serializing_if = "Option::is_none")]
12    _meta: Option<Cow<'a, Meta>>,
13    #[serde(flatten)]
14    _rest: P,
15}
16
17#[derive(Serialize, Deserialize)]
18struct Proxy<'a, M, P> {
19    method: M,
20    params: WithMeta<'a, P>,
21}
22
23#[derive(Serialize, Deserialize)]
24struct ProxyOptionalParam<'a, M, P> {
25    method: M,
26    params: Option<WithMeta<'a, P>>,
27}
28
29#[derive(Serialize, Deserialize)]
30struct ProxyNoParam<M> {
31    method: M,
32}
33
34impl<M, R> Serialize for Request<M, R>
35where
36    M: Serialize,
37    R: Serialize,
38{
39    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
40    where
41        S: serde::Serializer,
42    {
43        let extensions = &self.extensions;
44        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
45        Proxy::serialize(
46            &Proxy {
47                method: &self.method,
48                params: WithMeta {
49                    _rest: &self.params,
50                    _meta,
51                },
52            },
53            serializer,
54        )
55    }
56}
57
58impl<'de, M, R> Deserialize<'de> for Request<M, R>
59where
60    M: Deserialize<'de>,
61    R: Deserialize<'de>,
62{
63    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
64    where
65        D: serde::Deserializer<'de>,
66    {
67        let body = Proxy::deserialize(deserializer)?;
68        let _meta = body.params._meta.map(|m| m.into_owned());
69        let mut extensions = Extensions::new();
70        if let Some(meta) = _meta {
71            extensions.insert(meta);
72        }
73        Ok(Request {
74            extensions,
75            method: body.method,
76            params: body.params._rest,
77        })
78    }
79}
80
81impl<M, R> Serialize for RequestOptionalParam<M, R>
82where
83    M: Serialize,
84    R: Serialize,
85{
86    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
87    where
88        S: serde::Serializer,
89    {
90        let extensions = &self.extensions;
91        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
92        Proxy::serialize(
93            &Proxy {
94                method: &self.method,
95                params: WithMeta {
96                    _rest: &self.params,
97                    _meta,
98                },
99            },
100            serializer,
101        )
102    }
103}
104
105impl<'de, M, R> Deserialize<'de> for RequestOptionalParam<M, R>
106where
107    M: Deserialize<'de>,
108    R: Deserialize<'de>,
109{
110    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
111    where
112        D: serde::Deserializer<'de>,
113    {
114        let body = ProxyOptionalParam::<'_, _, Option<R>>::deserialize(deserializer)?;
115        let mut params = None;
116        let mut _meta = None;
117        if let Some(body_params) = body.params {
118            params = body_params._rest;
119            _meta = body_params._meta.map(|m| m.into_owned());
120        }
121        let mut extensions = Extensions::new();
122        if let Some(meta) = _meta {
123            extensions.insert(meta);
124        }
125        Ok(RequestOptionalParam {
126            extensions,
127            method: body.method,
128            params,
129        })
130    }
131}
132
133impl<M> Serialize for RequestNoParam<M>
134where
135    M: Serialize,
136{
137    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
138    where
139        S: serde::Serializer,
140    {
141        let extensions = &self.extensions;
142        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
143        ProxyNoParam::serialize(
144            &ProxyNoParam {
145                method: &self.method,
146            },
147            serializer,
148        )
149    }
150}
151
152impl<'de, M> Deserialize<'de> for RequestNoParam<M>
153where
154    M: Deserialize<'de>,
155{
156    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
157    where
158        D: serde::Deserializer<'de>,
159    {
160        let body = ProxyNoParam::<_>::deserialize(deserializer)?;
161        let extensions = Extensions::new();
162        Ok(RequestNoParam {
163            extensions,
164            method: body.method,
165        })
166    }
167}
168
169impl<M, R> Serialize for Notification<M, R>
170where
171    M: Serialize,
172    R: Serialize,
173{
174    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
175    where
176        S: serde::Serializer,
177    {
178        let extensions = &self.extensions;
179        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
180        Proxy::serialize(
181            &Proxy {
182                method: &self.method,
183                params: WithMeta {
184                    _rest: &self.params,
185                    _meta,
186                },
187            },
188            serializer,
189        )
190    }
191}
192
193impl<'de, M, R> Deserialize<'de> for Notification<M, R>
194where
195    M: Deserialize<'de>,
196    R: Deserialize<'de>,
197{
198    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
199    where
200        D: serde::Deserializer<'de>,
201    {
202        let body = Proxy::deserialize(deserializer)?;
203        let _meta = body.params._meta.map(|m| m.into_owned());
204        let mut extensions = Extensions::new();
205        if let Some(meta) = _meta {
206            extensions.insert(meta);
207        }
208        Ok(Notification {
209            extensions,
210            method: body.method,
211            params: body.params._rest,
212        })
213    }
214}
215
216impl<M> Serialize for NotificationNoParam<M>
217where
218    M: Serialize,
219{
220    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
221    where
222        S: serde::Serializer,
223    {
224        let extensions = &self.extensions;
225        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
226        ProxyNoParam::serialize(
227            &ProxyNoParam {
228                method: &self.method,
229            },
230            serializer,
231        )
232    }
233}
234
235impl<'de, M> Deserialize<'de> for NotificationNoParam<M>
236where
237    M: Deserialize<'de>,
238{
239    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
240    where
241        D: serde::Deserializer<'de>,
242    {
243        let body = ProxyNoParam::<_>::deserialize(deserializer)?;
244        let extensions = Extensions::new();
245        Ok(NotificationNoParam {
246            extensions,
247            method: body.method,
248        })
249    }
250}
251
252impl Serialize for CustomRequest {
253    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
254    where
255        S: serde::Serializer,
256    {
257        let extensions = &self.extensions;
258        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
259        let params = self.params.as_ref();
260
261        let params = if _meta.is_some() || params.is_some() {
262            Some(WithMeta {
263                _meta,
264                _rest: &self.params,
265            })
266        } else {
267            None
268        };
269
270        ProxyOptionalParam::serialize(
271            &ProxyOptionalParam {
272                method: &self.method,
273                params,
274            },
275            serializer,
276        )
277    }
278}
279
280impl<'de> Deserialize<'de> for CustomRequest {
281    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
282    where
283        D: serde::Deserializer<'de>,
284    {
285        let body =
286            ProxyOptionalParam::<'_, _, Option<serde_json::Value>>::deserialize(deserializer)?;
287        let mut params = None;
288        let mut _meta = None;
289        if let Some(body_params) = body.params {
290            params = body_params._rest;
291            _meta = body_params._meta.map(|m| m.into_owned());
292        }
293        let mut extensions = Extensions::new();
294        if let Some(meta) = _meta {
295            extensions.insert(meta);
296        }
297        Ok(CustomRequest {
298            extensions,
299            method: body.method,
300            params,
301        })
302    }
303}
304
305impl Serialize for CustomNotification {
306    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
307    where
308        S: serde::Serializer,
309    {
310        let extensions = &self.extensions;
311        let _meta = extensions.get::<Meta>().map(Cow::Borrowed);
312        let params = self.params.as_ref();
313
314        let params = if _meta.is_some() || params.is_some() {
315            Some(WithMeta {
316                _meta,
317                _rest: &self.params,
318            })
319        } else {
320            None
321        };
322
323        ProxyOptionalParam::serialize(
324            &ProxyOptionalParam {
325                method: &self.method,
326                params,
327            },
328            serializer,
329        )
330    }
331}
332
333impl<'de> Deserialize<'de> for CustomNotification {
334    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
335    where
336        D: serde::Deserializer<'de>,
337    {
338        let body =
339            ProxyOptionalParam::<'_, _, Option<serde_json::Value>>::deserialize(deserializer)?;
340        let mut params = None;
341        let mut _meta = None;
342        if let Some(body_params) = body.params {
343            params = body_params._rest;
344            _meta = body_params._meta.map(|m| m.into_owned());
345        }
346        let mut extensions = Extensions::new();
347        if let Some(meta) = _meta {
348            extensions.insert(meta);
349        }
350        Ok(CustomNotification {
351            extensions,
352            method: body.method,
353            params,
354        })
355    }
356}
357
358#[cfg(test)]
359mod test {
360    use serde_json::json;
361
362    use crate::model::ListToolsRequest;
363
364    #[test]
365    fn test_deserialize_lost_tools_request() {
366        let _req: ListToolsRequest = serde_json::from_value(json!(
367            {
368                "method": "tools/list",
369            }
370        ))
371        .unwrap();
372    }
373}