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 let mut writer = std::io::BufWriter::new(&mut self.data);
30
31 if !self.first {
33 writer.write_all(b"\r\n")?;
34 }
35
36 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 writer.write_all(headers.as_bytes())?;
45
46 writer.write_all(b"\r\n")?;
48 writer.write_all(b"\r\n")?;
49
50 io::copy(&mut reader, &mut writer)
52 }
53
54 pub fn finish(&mut self) -> io::Result<()> {
55 let mut writer = std::io::BufWriter::new(&mut self.data);
57
58 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}