adk_anthropic/types/
document_block.rs1use serde::{Deserialize, Serialize};
2
3use crate::types::{
4 Base64PdfSource, CacheControlEphemeral, CitationsConfig, ContentBlockSourceParam, FileSource,
5 PlainTextSource, UrlPdfSource,
6};
7
8#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10#[serde(tag = "type")]
11pub enum DocumentSource {
12 #[serde(rename = "base64")]
14 Base64Pdf(Base64PdfSource),
15
16 #[serde(rename = "text")]
18 PlainText(PlainTextSource),
19
20 #[serde(rename = "content")]
22 ContentBlock(ContentBlockSourceParam),
23
24 #[serde(rename = "url")]
26 UrlPdf(UrlPdfSource),
27
28 #[serde(rename = "file")]
30 File(FileSource),
31}
32
33impl From<Base64PdfSource> for DocumentSource {
34 fn from(source: Base64PdfSource) -> Self {
35 DocumentSource::Base64Pdf(source)
36 }
37}
38
39impl From<PlainTextSource> for DocumentSource {
40 fn from(source: PlainTextSource) -> Self {
41 DocumentSource::PlainText(source)
42 }
43}
44
45impl From<ContentBlockSourceParam> for DocumentSource {
46 fn from(source: ContentBlockSourceParam) -> Self {
47 DocumentSource::ContentBlock(source)
48 }
49}
50
51impl From<UrlPdfSource> for DocumentSource {
52 fn from(source: UrlPdfSource) -> Self {
53 DocumentSource::UrlPdf(source)
54 }
55}
56
57impl From<FileSource> for DocumentSource {
58 fn from(source: FileSource) -> Self {
59 DocumentSource::File(source)
60 }
61}
62
63#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
65pub struct DocumentBlock {
66 pub source: DocumentSource,
68
69 #[serde(skip_serializing_if = "Option::is_none")]
71 pub cache_control: Option<CacheControlEphemeral>,
72
73 #[serde(skip_serializing_if = "Option::is_none")]
75 pub citations: Option<CitationsConfig>,
76
77 #[serde(skip_serializing_if = "Option::is_none")]
79 pub context: Option<String>,
80
81 #[serde(skip_serializing_if = "Option::is_none")]
83 pub title: Option<String>,
84}
85
86impl DocumentBlock {
87 pub fn new(source: DocumentSource) -> Self {
89 Self { source, cache_control: None, citations: None, context: None, title: None }
90 }
91
92 pub fn new_with_base64_pdf(source: Base64PdfSource) -> Self {
94 Self::new(DocumentSource::Base64Pdf(source))
95 }
96
97 pub fn new_with_plain_text(source: PlainTextSource) -> Self {
99 Self::new(DocumentSource::PlainText(source))
100 }
101
102 pub fn new_with_content_block(source: ContentBlockSourceParam) -> Self {
104 Self::new(DocumentSource::ContentBlock(source))
105 }
106
107 pub fn new_with_url_pdf(source: UrlPdfSource) -> Self {
109 Self::new(DocumentSource::UrlPdf(source))
110 }
111
112 pub fn with_cache_control(mut self, cache_control: CacheControlEphemeral) -> Self {
114 self.cache_control = Some(cache_control);
115 self
116 }
117
118 pub fn with_citations(mut self, citations: CitationsConfig) -> Self {
120 self.citations = Some(citations);
121 self
122 }
123
124 pub fn with_context(mut self, context: String) -> Self {
126 self.context = Some(context);
127 self
128 }
129
130 pub fn with_title(mut self, title: String) -> Self {
132 self.title = Some(title);
133 self
134 }
135}
136
137#[cfg(test)]
138mod tests {
139 use super::*;
140 use serde_json::{json, to_value};
141
142 #[test]
143 fn document_block_with_base64_pdf() {
144 let base64_source =
145 Base64PdfSource::new("data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKN".to_string());
146
147 let document_block = DocumentBlock::new_with_base64_pdf(base64_source);
148 let json = to_value(&document_block).unwrap();
149
150 assert_eq!(
151 json,
152 json!({
153 "source": {
154 "type": "base64",
155 "data": "data:application/pdf;base64,JVBERi0xLjcKJeLjz9MKN",
156 "media_type": "application/pdf"
157 }
158 })
159 );
160 }
161
162 #[test]
163 fn document_block_with_plain_text() {
164 let text_source = PlainTextSource::new("Sample text content".to_string());
165
166 let document_block = DocumentBlock::new_with_plain_text(text_source);
167 let json = to_value(&document_block).unwrap();
168
169 assert_eq!(
170 json,
171 json!({
172 "source": {
173 "type": "text",
174 "data": "Sample text content",
175 "media_type": "text/plain"
176 }
177 })
178 );
179 }
180
181 #[test]
182 fn document_block_with_content_block() {
183 let content_source = ContentBlockSourceParam::from_string_ref("Sample content");
184
185 let document_block = DocumentBlock::new_with_content_block(content_source);
186 let json = to_value(&document_block).unwrap();
187
188 assert_eq!(
189 json,
190 json!({
191 "source": {
192 "type": "content",
193 "content": "Sample content"
194 }
195 })
196 );
197 }
198
199 #[test]
200 fn document_block_with_url_pdf() {
201 let url_source = UrlPdfSource::new("https://example.com/document.pdf".to_string());
202
203 let document_block = DocumentBlock::new_with_url_pdf(url_source);
204 let json = to_value(&document_block).unwrap();
205
206 assert_eq!(
207 json,
208 json!({
209 "source": {
210 "type": "url",
211 "url": "https://example.com/document.pdf"
212 }
213 })
214 );
215 }
216
217 #[test]
218 fn document_block_with_all_fields() {
219 let url_source = UrlPdfSource::new("https://example.com/document.pdf".to_string());
220 let cache_control = CacheControlEphemeral::new();
221 let citations = CitationsConfig::enabled();
222
223 let document_block = DocumentBlock::new_with_url_pdf(url_source)
224 .with_cache_control(cache_control)
225 .with_citations(citations)
226 .with_context("Document context".to_string())
227 .with_title("Document Title".to_string());
228
229 let json = to_value(&document_block).unwrap();
230
231 assert_eq!(
232 json,
233 json!({
234 "source": {
235 "type": "url",
236 "url": "https://example.com/document.pdf"
237 },
238 "cache_control": {
239 "type": "ephemeral"
240 },
241 "citations": {
242 "enabled": true
243 },
244 "context": "Document context",
245 "title": "Document Title"
246 })
247 );
248 }
249}