gitbutler/gitbutler-app/src/writer.rs

115 lines
3.7 KiB
Rust
Raw Normal View History

2023-04-12 15:14:39 +03:00
use std::io::Write;
2023-04-14 13:25:07 +03:00
use anyhow::{Context, Result};
2023-04-12 15:14:39 +03:00
pub trait Writer {
2023-04-17 12:13:57 +03:00
fn write(&self, path: &str, contents: &[u8]) -> Result<()>;
2023-06-15 14:08:00 +03:00
fn append_string(&self, path: &str, contents: &str) -> Result<()>;
fn remove(&self, path: &str) -> Result<()>;
fn write_usize(&self, path: &str, contents: &usize) -> Result<()> {
2023-06-29 18:11:02 +03:00
self.write_string(path, &contents.to_string())
}
2023-06-05 17:12:25 +03:00
fn write_u128(&self, path: &str, contents: &u128) -> Result<()> {
self.write_string(path, &contents.to_string())
}
fn write_bool(&self, path: &str, contents: &bool) -> Result<()> {
self.write_string(path, &contents.to_string())
}
2023-04-17 12:13:57 +03:00
fn write_string(&self, path: &str, contents: &str) -> Result<()> {
self.write(path, contents.as_bytes())
}
2023-04-12 15:14:39 +03:00
}
2023-04-17 12:13:57 +03:00
pub struct DirWriter {
root: std::path::PathBuf,
2023-04-12 15:14:39 +03:00
}
2023-05-31 10:29:26 +03:00
impl DirWriter {
2023-04-17 12:13:57 +03:00
pub fn open(root: std::path::PathBuf) -> Self {
2023-04-13 14:37:46 +03:00
Self { root }
}
2023-04-12 15:14:39 +03:00
}
2023-04-17 12:13:57 +03:00
impl Writer for DirWriter {
fn write(&self, path: &str, contents: &[u8]) -> Result<()> {
2023-04-13 14:37:46 +03:00
let file_path = self.root.join(path);
2023-10-19 16:25:27 +03:00
let dir_path = file_path.parent().context("failed to get parent")?;
2023-06-05 17:12:25 +03:00
std::fs::create_dir_all(dir_path).context("failed to create directory")?;
std::fs::write(file_path, contents)?;
2023-04-12 15:14:39 +03:00
Ok(())
}
fn append_string(&self, path: &str, contents: &str) -> Result<()> {
2023-04-13 14:37:46 +03:00
let file_path = self.root.join(path);
2023-10-19 16:25:27 +03:00
let dir_path = file_path.parent().context("failed to get parent")?;
2023-06-05 17:12:25 +03:00
std::fs::create_dir_all(dir_path).context("failed to create directory")?;
2023-04-12 15:14:39 +03:00
let mut file = std::fs::OpenOptions::new()
.create(true)
.append(true)
.open(file_path)
.with_context(|| format!("failed to open file: {}", path))?;
file.write_all(contents.as_bytes())?;
Ok(())
}
2023-06-07 13:43:07 +03:00
fn remove(&self, path: &str) -> Result<()> {
let file_path = self.root.join(path);
2023-07-01 11:30:00 +03:00
if file_path.is_dir() {
match std::fs::remove_dir_all(file_path) {
Ok(()) => Ok(()),
2023-07-01 11:30:00 +03:00
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(e.into()),
}
} else {
match std::fs::remove_file(file_path) {
Ok(()) => Ok(()),
2023-07-01 11:30:00 +03:00
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Ok(()),
Err(e) => Err(e.into()),
}
2023-06-07 13:43:07 +03:00
}
}
2023-04-12 15:14:39 +03:00
}
2023-06-05 17:12:25 +03:00
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_write() {
let root = tempfile::tempdir().unwrap();
let writer = DirWriter::open(root.path().to_path_buf());
writer.write("foo/bar", b"baz").unwrap();
assert_eq!(
std::fs::read_to_string(root.path().join("foo/bar")).unwrap(),
"baz"
);
}
#[test]
fn test_append_string() {
let root = tempfile::tempdir().unwrap();
let writer = DirWriter::open(root.path().to_path_buf());
writer.append_string("foo/bar", "baz").unwrap();
writer.append_string("foo/bar", "qux").unwrap();
assert_eq!(
std::fs::read_to_string(root.path().join("foo/bar")).unwrap(),
"bazqux"
);
}
2023-06-07 13:43:07 +03:00
#[test]
fn test_remove() {
let root = tempfile::tempdir().unwrap();
let writer = DirWriter::open(root.path().to_path_buf());
writer.remove("foo/bar").unwrap();
assert!(!root.path().join("foo/bar").exists());
writer.write("foo/bar", b"baz").unwrap();
writer.remove("foo/bar").unwrap();
assert!(!root.path().join("foo/bar").exists());
2023-07-01 11:30:00 +03:00
writer.write("parent/child", b"baz").unwrap();
writer.remove("parent").unwrap();
assert!(!root.path().join("parent").exists());
2023-06-07 13:43:07 +03:00
}
2023-06-05 17:12:25 +03:00
}