poem_mcpserver/
content.rs1use std::fmt::Display;
4
5use base64::{Engine, engine::general_purpose::STANDARD};
6use serde::Serialize;
7
8use crate::protocol::content::Content;
9
10pub trait IntoContent {
12 fn into_content(self) -> Content;
14}
15
16impl IntoContent for Content {
17 #[inline]
18 fn into_content(self) -> Content {
19 self
20 }
21}
22
23pub trait IntoContents {
25 fn into_contents(self) -> Vec<Content>;
27}
28
29impl<T> IntoContents for T
30where
31 T: IntoContent,
32{
33 fn into_contents(self) -> Vec<Content> {
34 vec![self.into_content()]
35 }
36}
37
38impl<T> IntoContents for Vec<T>
39where
40 T: IntoContent,
41{
42 fn into_contents(self) -> Vec<Content> {
43 self.into_iter().map(IntoContent::into_content).collect()
44 }
45}
46
47pub struct ContentsIter<T>(pub T);
49
50impl<T> IntoContents for ContentsIter<T>
51where
52 T: IntoIterator,
53 T::Item: IntoContent,
54{
55 fn into_contents(self) -> Vec<Content> {
56 self.0.into_iter().map(IntoContent::into_content).collect()
57 }
58}
59
60#[derive(Debug)]
62pub struct Text<T>(pub T);
63
64impl<T> IntoContent for Text<T>
65where
66 T: Display,
67{
68 fn into_content(self) -> Content {
69 Content::Text {
70 text: self.0.to_string(),
71 }
72 }
73}
74
75#[derive(Debug)]
77pub struct Image<T> {
78 data: T,
79 mime_type: String,
80}
81
82impl<T> Image<T> {
83 #[inline]
85 pub fn new(data: T, mime_type: impl Into<String>) -> Self {
86 Self {
87 data,
88 mime_type: mime_type.into(),
89 }
90 }
91}
92
93impl<T> IntoContent for Image<T>
94where
95 T: AsRef<[u8]>,
96{
97 fn into_content(self) -> Content {
98 Content::Image {
99 data: STANDARD.encode(self.data),
100 mime_type: self.mime_type,
101 }
102 }
103}
104
105#[derive(Debug, Clone, Copy)]
107pub struct Json<T>(pub T);
108
109impl<T> IntoContent for Json<T>
110where
111 T: Serialize,
112{
113 fn into_content(self) -> Content {
114 Content::Text {
115 text: serde_json::to_string(&self.0).unwrap_or_default(),
116 }
117 }
118}