multipart_rs/
writer.rs

1use std::io::{self, Read, Write};
2use uuid::Uuid;
3
4pub struct MultipartWriter {
5    pub boundary: String,
6    pub data: Vec<u8>,
7    first: bool,
8}
9
10impl MultipartWriter {
11    pub fn new() -> MultipartWriter {
12        MultipartWriter {
13            boundary: format!("{}", Uuid::new_v4()),
14            first: true,
15            data: Vec::new(),
16        }
17    }
18
19    pub fn new_with_boundary(boundary: &str) -> MultipartWriter {
20        MultipartWriter {
21            boundary: boundary.to_string(),
22            first: true,
23            data: Vec::new(),
24        }
25    }
26
27    pub fn add(&mut self, mut reader: impl Read, headers: &str) -> io::Result<u64> {
28        // writer for our buffer
29        let mut writer = std::io::BufWriter::new(&mut self.data);
30
31        // write the boundary
32        if !self.first {
33            writer.write_all(b"\r\n")?;
34        }
35
36        // set first to false
37        self.first = false;
38
39        writer.write_all(b"--")?;
40        writer.write_all(self.boundary.as_bytes())?;
41        writer.write_all(b"\r\n")?;
42
43        // write the content type
44        writer.write_all(headers.as_bytes())?;
45
46        // write an empty line
47        writer.write_all(b"\r\n")?;
48        writer.write_all(b"\r\n")?;
49
50        // write the content
51        io::copy(&mut reader, &mut writer)
52    }
53
54    pub fn finish(&mut self) -> io::Result<()> {
55        // writer for our buffer
56        let mut writer = std::io::BufWriter::new(&mut self.data);
57
58        // write the final boundary
59        writer.write_all(b"\r\n")?;
60        writer.write_all(b"--")?;
61        writer.write_all(self.boundary.as_bytes())?;
62        writer.write_all(b"--")?;
63        writer.write_all(b"\r\n")?;
64
65        Ok(())
66    }
67}