1use std::collections::HashMap;
2use std::io;
3
4use io::BufRead;
5use io::Read;
6
7use base64::Engine;
8
9#[derive(serde::Serialize)]
10pub struct Blob {
11 pub name: String,
13
14 pub content_type: String,
15
16 pub content_encoding: String,
17
18 pub content_transfer_encoding: String,
20
21 pub body: String,
23
24 #[serde(skip_serializing_if = "Option::is_none")]
25 pub metadata: Option<HashMap<String, String>>,
26}
27
28pub struct BlobBuilder {
29 content_type: String,
30 content_encoding: String,
31 max_bytes: u64,
32 metadata: Option<HashMap<String, String>>,
33}
34
35impl BlobBuilder {
36 pub fn bytes2blob(&self, blob: &[u8], name: String) -> Blob {
37 let encoded: String = base64::engine::general_purpose::STANDARD.encode(blob);
38 Blob {
39 name,
40 content_type: self.content_type.clone(),
41 content_encoding: self.content_encoding.clone(),
42 content_transfer_encoding: "base64".into(),
43 body: encoded,
44 metadata: self.metadata.clone(),
45 }
46 }
47
48 pub fn rdr2blob<R>(&self, rdr: R, name: String) -> Result<Blob, io::Error>
49 where
50 R: BufRead,
51 {
52 let mut taken = rdr.take(self.max_bytes);
53 let mut buf: Vec<u8> = vec![];
54 taken.read_to_end(&mut buf)?;
55 Ok(self.bytes2blob(&buf, name))
56 }
57}
58
59pub const CONTENT_TYPE_DEFAULT: &str = "application/octet-stream";
60pub const CONTENT_ENCODING_DEFAULT: &str = "";
61pub const MAX_BYTES_DEFAULT: u64 = 1048576;
62
63impl Default for BlobBuilder {
64 fn default() -> Self {
65 Self {
66 content_type: CONTENT_TYPE_DEFAULT.into(),
67 content_encoding: CONTENT_ENCODING_DEFAULT.into(),
68 max_bytes: MAX_BYTES_DEFAULT,
69 metadata: None,
70 }
71 }
72}
73
74impl BlobBuilder {
75 pub fn with_content_type(mut self, ctyp: String) -> Self {
76 self.content_type = ctyp;
77 self
78 }
79
80 pub fn with_content_encoding(mut self, enc: String) -> Self {
81 self.content_encoding = enc;
82 self
83 }
84
85 pub fn with_max_bytes(mut self, mb: u64) -> Self {
86 self.max_bytes = mb;
87 self
88 }
89
90 pub fn with_metadata(mut self, metadata: HashMap<String, String>) -> Self {
91 self.metadata = Some(metadata);
92 self
93 }
94}