1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5
6use super::{Annotations, Request, Notification};
7use super::messages::MessageResult;
8
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
11pub struct Resource {
12 pub uri: String,
14
15 pub name: String,
17
18 #[serde(skip_serializing_if = "Option::is_none")]
20 pub description: Option<String>,
21
22 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
24 pub mime_type: Option<String>,
25
26 #[serde(skip_serializing_if = "Option::is_none")]
28 pub annotations: Option<Annotations>,
29
30 #[serde(skip_serializing_if = "Option::is_none")]
32 pub size: Option<i64>,
33}
34
35impl Resource {
36 pub fn new(uri: impl Into<String>, name: impl Into<String>) -> Self {
38 Self {
39 uri: uri.into(),
40 name: name.into(),
41 description: None,
42 mime_type: None,
43 annotations: None,
44 size: None,
45 }
46 }
47
48 pub fn with_description(uri: impl Into<String>, name: impl Into<String>, description: impl Into<String>) -> Self {
50 Self {
51 uri: uri.into(),
52 name: name.into(),
53 description: Some(description.into()),
54 mime_type: None,
55 annotations: None,
56 size: None,
57 }
58 }
59
60 pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
62 self.mime_type = Some(mime_type.into());
63 self
64 }
65
66 pub fn with_annotations(mut self, annotations: Annotations) -> Self {
68 self.annotations = Some(annotations);
69 self
70 }
71
72 pub fn with_size(mut self, size: i64) -> Self {
74 self.size = Some(size);
75 self
76 }
77}
78
79impl Default for Resource {
80 fn default() -> Self {
81 Self {
82 uri: String::new(),
83 name: String::new(),
84 description: None,
85 mime_type: None,
86 annotations: None,
87 size: None,
88 }
89 }
90}
91
92#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
94pub struct ResourceTemplate {
95 #[serde(rename = "uriTemplate")]
97 pub uri_template: String,
98
99 pub name: String,
101
102 #[serde(skip_serializing_if = "Option::is_none")]
104 pub description: Option<String>,
105
106 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
108 pub mime_type: Option<String>,
109
110 #[serde(skip_serializing_if = "Option::is_none")]
112 pub annotations: Option<Annotations>,
113}
114
115impl ResourceTemplate {
116 pub fn new(uri_template: impl Into<String>, name: impl Into<String>) -> Self {
118 Self {
119 uri_template: uri_template.into(),
120 name: name.into(),
121 description: None,
122 mime_type: None,
123 annotations: None,
124 }
125 }
126
127 pub fn with_description(
129 uri_template: impl Into<String>,
130 name: impl Into<String>,
131 description: impl Into<String>,
132 ) -> Self {
133 Self {
134 uri_template: uri_template.into(),
135 name: name.into(),
136 description: Some(description.into()),
137 mime_type: None,
138 annotations: None,
139 }
140 }
141
142 pub fn with_mime_type(mut self, mime_type: impl Into<String>) -> Self {
144 self.mime_type = Some(mime_type.into());
145 self
146 }
147
148 pub fn with_annotations(mut self, annotations: Annotations) -> Self {
150 self.annotations = Some(annotations);
151 self
152 }
153}
154
155#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
157pub struct ResourceContents {
158 pub uri: String,
160
161 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
163 pub mime_type: Option<String>,
164}
165
166impl ResourceContents {
167 pub fn new(uri: impl Into<String>) -> Self {
169 Self {
170 uri: uri.into(),
171 mime_type: None,
172 }
173 }
174
175 pub fn with_mime_type(uri: impl Into<String>, mime_type: impl Into<String>) -> Self {
177 Self {
178 uri: uri.into(),
179 mime_type: Some(mime_type.into()),
180 }
181 }
182}
183
184#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
186pub struct TextResourceContents {
187 pub uri: String,
189
190 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
192 pub mime_type: Option<String>,
193
194 pub text: String,
196}
197
198impl TextResourceContents {
199 pub fn new(uri: impl Into<String>, text: impl Into<String>) -> Self {
201 Self {
202 uri: uri.into(),
203 mime_type: None,
204 text: text.into(),
205 }
206 }
207
208 pub fn with_mime_type(uri: impl Into<String>, text: impl Into<String>, mime_type: impl Into<String>) -> Self {
210 Self {
211 uri: uri.into(),
212 mime_type: Some(mime_type.into()),
213 text: text.into(),
214 }
215 }
216}
217
218#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
220pub struct BlobResourceContents {
221 pub uri: String,
223
224 #[serde(rename = "mimeType", skip_serializing_if = "Option::is_none")]
226 pub mime_type: Option<String>,
227
228 pub blob: String,
230}
231
232impl BlobResourceContents {
233 pub fn new(uri: impl Into<String>, blob: impl Into<String>) -> Self {
235 Self {
236 uri: uri.into(),
237 mime_type: None,
238 blob: blob.into(),
239 }
240 }
241
242 pub fn with_mime_type(uri: impl Into<String>, blob: impl Into<String>, mime_type: impl Into<String>) -> Self {
244 Self {
245 uri: uri.into(),
246 mime_type: Some(mime_type.into()),
247 blob: blob.into(),
248 }
249 }
250}
251
252#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
254pub struct ListResourcesRequest {
255 pub method: String,
257
258 #[serde(skip_serializing_if = "Option::is_none")]
260 pub params: Option<ListResourcesParams>,
261}
262
263impl Request for ListResourcesRequest {
264 const METHOD: &'static str = "resources/list";
265
266 fn method(&self) -> &str {
267 &self.method
268 }
269
270 fn params(&self) -> Option<&serde_json::Value> {
271 None
272 }
273}
274
275impl ListResourcesRequest {
276 pub fn new() -> Self {
278 Self {
279 method: Self::METHOD.to_string(),
280 params: None,
281 }
282 }
283
284 pub fn with_cursor(cursor: impl Into<String>) -> Self {
286 Self {
287 method: Self::METHOD.to_string(),
288 params: Some(ListResourcesParams {
289 cursor: Some(cursor.into()),
290 }),
291 }
292 }
293}
294
295#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
297pub struct ListResourcesParams {
298 #[serde(skip_serializing_if = "Option::is_none")]
300 pub cursor: Option<String>,
301}
302
303#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
305pub struct ListResourcesResult {
306 pub resources: Vec<Resource>,
308
309 #[serde(rename = "nextCursor", skip_serializing_if = "Option::is_none")]
311 pub next_cursor: Option<String>,
312
313 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
315 pub meta: Option<super::messages::ResultMeta>,
316}
317
318impl MessageResult for ListResourcesResult {}
319
320impl ListResourcesResult {
321 pub fn new(resources: Vec<Resource>) -> Self {
323 Self {
324 resources,
325 next_cursor: None,
326 meta: None,
327 }
328 }
329
330 pub fn with_next_cursor(resources: Vec<Resource>, next_cursor: impl Into<String>) -> Self {
332 Self {
333 resources,
334 next_cursor: Some(next_cursor.into()),
335 meta: None,
336 }
337 }
338}
339
340#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
342pub struct ReadResourceRequest {
343 pub method: String,
345
346 pub params: ReadResourceParams,
348}
349
350impl Request for ReadResourceRequest {
351 const METHOD: &'static str = "resources/read";
352
353 fn method(&self) -> &str {
354 &self.method
355 }
356
357 fn params(&self) -> Option<&serde_json::Value> {
358 None
359 }
360}
361
362impl ReadResourceRequest {
363 pub fn new(uri: impl Into<String>) -> Self {
365 Self {
366 method: Self::METHOD.to_string(),
367 params: ReadResourceParams {
368 uri: uri.into(),
369 },
370 }
371 }
372}
373
374#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
376pub struct ReadResourceParams {
377 pub uri: String,
379}
380
381#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
383pub struct ReadResourceResult {
384 pub contents: Vec<ResourceContent>,
386
387 #[serde(rename = "_meta", skip_serializing_if = "Option::is_none")]
389 pub meta: Option<super::messages::ResultMeta>,
390}
391
392impl ReadResourceResult {
393 pub fn new(contents: Vec<ResourceContent>) -> Self {
395 Self {
396 contents,
397 meta: None,
398 }
399 }
400}
401
402#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
404#[serde(untagged)]
405pub enum ResourceContent {
406 Text(TextResourceContents),
408 Blob(BlobResourceContents),
410}
411
412#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
414pub struct SubscribeRequest {
415 pub method: String,
417
418 pub params: SubscribeParams,
420}
421
422impl Request for SubscribeRequest {
423 const METHOD: &'static str = "resources/subscribe";
424
425 fn method(&self) -> &str {
426 &self.method
427 }
428
429 fn params(&self) -> Option<&serde_json::Value> {
430 None
431 }
432}
433
434impl SubscribeRequest {
435 pub fn new(uri: impl Into<String>) -> Self {
437 Self {
438 method: Self::METHOD.to_string(),
439 params: SubscribeParams {
440 uri: uri.into(),
441 },
442 }
443 }
444}
445
446#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
448pub struct SubscribeParams {
449 pub uri: String,
451}
452
453#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
455pub struct UnsubscribeRequest {
456 pub method: String,
458
459 pub params: UnsubscribeParams,
461}
462
463impl Request for UnsubscribeRequest {
464 const METHOD: &'static str = "resources/unsubscribe";
465
466 fn method(&self) -> &str {
467 &self.method
468 }
469
470 fn params(&self) -> Option<&serde_json::Value> {
471 None
472 }
473}
474
475impl UnsubscribeRequest {
476 pub fn new(uri: impl Into<String>) -> Self {
478 Self {
479 method: Self::METHOD.to_string(),
480 params: UnsubscribeParams {
481 uri: uri.into(),
482 },
483 }
484 }
485}
486
487#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
489pub struct UnsubscribeParams {
490 pub uri: String,
492}
493
494#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
496pub struct ResourceUpdatedNotification {
497 pub method: String,
499
500 pub params: ResourceUpdatedParams,
502}
503
504impl Notification for ResourceUpdatedNotification {
505 const METHOD: &'static str = "notifications/resources/updated";
506
507 fn method(&self) -> &str {
508 &self.method
509 }
510
511 fn params(&self) -> Option<&serde_json::Value> {
512 None
513 }
514}
515
516impl ResourceUpdatedNotification {
517 pub fn new(uri: impl Into<String>) -> Self {
519 Self {
520 method: "notifications/resources/updated".to_string(),
521 params: ResourceUpdatedParams {
522 uri: uri.into(),
523 },
524 }
525 }
526}
527
528#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
530pub struct ResourceUpdatedParams {
531 pub uri: String,
533}
534
535#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
537pub struct ResourceListChangedNotification {
538 pub method: String,
540
541 #[serde(skip_serializing_if = "Option::is_none")]
543 pub params: Option<super::messages::NotificationParams>,
544}
545
546impl ResourceListChangedNotification {
547 pub fn new() -> Self {
549 Self {
550 method: "notifications/resources/list_changed".to_string(),
551 params: None,
552 }
553 }
554}
555
556#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
558pub struct EmbeddedResource {
559 pub r#type: String,
561
562 pub resource: ResourceContent,
564
565 #[serde(skip_serializing_if = "Option::is_none")]
567 pub annotations: Option<Annotations>,
568}
569
570impl EmbeddedResource {
571 pub fn text(uri: impl Into<String>, text: impl Into<String>) -> Self {
573 Self {
574 r#type: "resource".to_string(),
575 resource: ResourceContent::Text(TextResourceContents::new(uri, text)),
576 annotations: None,
577 }
578 }
579
580 pub fn blob(uri: impl Into<String>, blob: impl Into<String>) -> Self {
582 Self {
583 r#type: "resource".to_string(),
584 resource: ResourceContent::Blob(BlobResourceContents::new(uri, blob)),
585 annotations: None,
586 }
587 }
588
589 pub fn with_annotations(mut self, annotations: Annotations) -> Self {
591 self.annotations = Some(annotations);
592 self
593 }
594}
595
596#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
598pub struct ResourceReference {
599 pub r#type: String,
601
602 pub uri: String,
604}
605
606impl ResourceReference {
607 pub fn new(uri: impl Into<String>) -> Self {
609 Self {
610 r#type: "ref/resource".to_string(),
611 uri: uri.into(),
612 }
613 }
614}