rust_integration_services/file/
file_sender.rs

1use std::path::{Path, PathBuf};
2use tokio::{fs::OpenOptions, io::AsyncWriteExt};
3
4#[cfg(windows)]
5const NEW_LINE: &[u8] = b"\r\n";
6#[cfg(not(windows))]
7const NEW_LINE: &[u8] = b"\n";
8
9pub struct FileSender {
10    overwrite: bool,
11    target_path: PathBuf,
12}
13
14impl FileSender {
15    /// Builds a new FileSender with the full path to the target file.
16    /// 
17    /// If the file does not exist, it will be created.
18    pub fn new<T: AsRef<Path>>(target_path: T) -> Self {
19        FileSender  { 
20            overwrite: false,
21            target_path: target_path.as_ref().to_path_buf(),
22        }
23    }
24
25    /// This will overwrite the contents of the target file.
26    pub fn overwrite(mut self, overwrite: bool) -> Self {
27        self.overwrite = overwrite;
28        self
29    }
30
31    /// Writes the bytes to the target file.
32    pub async fn send_bytes(self, bytes: &[u8]) -> tokio::io::Result<()> {
33        let mut file = OpenOptions::new().create(true).write(true).append(!self.overwrite).truncate(self.overwrite).open(&self.target_path).await?;
34
35        if !self.overwrite && file.metadata().await?.len() > 0 {
36            file.write_all(NEW_LINE).await?;
37        }
38
39        file.write_all(bytes).await?;
40        Ok(())
41    }
42
43    /// Writes the string to the target file.
44    pub async fn send_string<T: AsRef<str>>(self, string: T) -> tokio::io::Result<()> {
45        self.send_bytes(string.as_ref().as_bytes()).await
46    }
47
48    /// Copy the contents of the source file to the target file.
49    pub async fn send_copy<T: AsRef<Path>>(self, source_path: T) -> tokio::io::Result<()> {
50        self.copy(source_path, false).await
51    }
52
53    /// Copy the contents of the source file to the target file and delete the source file if successful.
54    pub async fn send_move<T: AsRef<Path>>(self, source_path: T) -> tokio::io::Result<()> {
55        self.copy(source_path, true).await
56    }
57
58    async fn copy<T: AsRef<Path>>(self, source_path: T, delete_file_on_success: bool) -> tokio::io::Result<()> {
59        tokio::fs::copy(&source_path, &self.target_path).await?;
60
61        if delete_file_on_success {
62            tokio::fs::remove_file(&source_path).await?;
63        }
64
65        Ok(())
66    }
67}