claudius/types/
base64_pdf_source.rs1use base64::Engine;
2use serde::{Deserialize, Serialize};
3use std::fs::File;
4use std::io::Read;
5use std::path::Path;
6
7#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
12pub struct Base64PdfSource {
13 pub data: String,
15
16 #[serde(default = "default_media_type")]
18 pub media_type: String,
19}
20
21fn default_media_type() -> String {
22 "application/pdf".to_string()
23}
24
25impl Base64PdfSource {
26 pub fn new(data: String) -> Self {
28 Self {
29 data,
30 media_type: default_media_type(),
31 }
32 }
33
34 pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Self, std::io::Error> {
39 let path = path.as_ref();
40
41 match path.extension().and_then(|ext| ext.to_str()) {
43 Some("pdf") => {}
44 _ => {
45 return Err(std::io::Error::new(
46 std::io::ErrorKind::InvalidInput,
47 "File extension must be .pdf",
48 ));
49 }
50 };
51
52 let mut file = File::open(path)?;
54 let mut buffer = Vec::new();
55 file.read_to_end(&mut buffer)?;
56
57 let data = base64::engine::general_purpose::STANDARD.encode(&buffer);
59
60 Ok(Self {
61 data,
62 media_type: default_media_type(),
63 })
64 }
65}
66
67#[cfg(test)]
68mod tests {
69 use super::*;
70
71 #[test]
72 fn serialization() {
73 let source = Base64PdfSource {
74 data: "SGVsbG8gV29ybGQ=".to_string(), media_type: "application/pdf".to_string(),
76 };
77
78 let json = serde_json::to_value(&source).unwrap();
79 let expected = serde_json::json!({
80 "data": "SGVsbG8gV29ybGQ=",
81 "media_type": "application/pdf"
82 });
83
84 assert_eq!(json, expected);
85 }
86
87 #[test]
88 fn deserialization() {
89 let json = serde_json::json!({
90 "data": "SGVsbG8gV29ybGQ=",
91 "media_type": "application/pdf"
92 });
93 let source: Base64PdfSource = serde_json::from_value(json).unwrap();
94
95 assert_eq!(source.data, "SGVsbG8gV29ybGQ=");
96 assert_eq!(source.media_type, "application/pdf");
97 }
98}