Skip to main content

adk_anthropic/types/
document_block.rs

1use serde::{Deserialize, Serialize};
2
3use crate::types::{
4    Base64PdfSource, CacheControlEphemeral, CitationsConfig, ContentBlockSourceParam, FileSource,
5    PlainTextSource, UrlPdfSource,
6};
7
8/// The source type for a document block, which can be one of several types.
9#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
10#[serde(tag = "type")]
11pub enum DocumentSource {
12    /// A Base64 encoded PDF source.
13    #[serde(rename = "base64")]
14    Base64Pdf(Base64PdfSource),
15
16    /// A plain text source.
17    #[serde(rename = "text")]
18    PlainText(PlainTextSource),
19
20    /// A content block source.
21    #[serde(rename = "content")]
22    ContentBlock(ContentBlockSourceParam),
23
24    /// A URL PDF source.
25    #[serde(rename = "url")]
26    UrlPdf(UrlPdfSource),
27
28    /// A file source referencing a server-side file.
29    #[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/// Parameters for a document block.
64#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
65pub struct DocumentBlock {
66    /// The source of the document.
67    pub source: DocumentSource,
68
69    /// Create a cache control breakpoint at this content block.
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub cache_control: Option<CacheControlEphemeral>,
72
73    /// Configuration for citations in this document.
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub citations: Option<CitationsConfig>,
76
77    /// Optional context for the document.
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub context: Option<String>,
80
81    /// Optional title for the document.
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub title: Option<String>,
84}
85
86impl DocumentBlock {
87    /// Create a new `DocumentBlock` with the given source.
88    pub fn new(source: DocumentSource) -> Self {
89        Self { source, cache_control: None, citations: None, context: None, title: None }
90    }
91
92    /// Create a new `DocumentBlock` with a Base64 PDF source.
93    pub fn new_with_base64_pdf(source: Base64PdfSource) -> Self {
94        Self::new(DocumentSource::Base64Pdf(source))
95    }
96
97    /// Create a new `DocumentBlock` with a plain text source.
98    pub fn new_with_plain_text(source: PlainTextSource) -> Self {
99        Self::new(DocumentSource::PlainText(source))
100    }
101
102    /// Create a new `DocumentBlock` with a content block source.
103    pub fn new_with_content_block(source: ContentBlockSourceParam) -> Self {
104        Self::new(DocumentSource::ContentBlock(source))
105    }
106
107    /// Create a new `DocumentBlock` with a URL PDF source.
108    pub fn new_with_url_pdf(source: UrlPdfSource) -> Self {
109        Self::new(DocumentSource::UrlPdf(source))
110    }
111
112    /// Add a cache control to this document block.
113    pub fn with_cache_control(mut self, cache_control: CacheControlEphemeral) -> Self {
114        self.cache_control = Some(cache_control);
115        self
116    }
117
118    /// Add citations configuration to this document block.
119    pub fn with_citations(mut self, citations: CitationsConfig) -> Self {
120        self.citations = Some(citations);
121        self
122    }
123
124    /// Add context to this document block.
125    pub fn with_context(mut self, context: String) -> Self {
126        self.context = Some(context);
127        self
128    }
129
130    /// Add a title to this document block.
131    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}