rs_blob2json/
lib.rs

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    /// The name of the blob. e.g., "blob.dat"
12    pub name: String,
13
14    pub content_type: String,
15
16    pub content_encoding: String,
17
18    /// (Always base64).
19    pub content_transfer_encoding: String,
20
21    /// Base64 encoded content(even if the content is human readable text).
22    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}