Compare commits

...

No commits in common. "1.0.0" and "main" have entirely different histories.
1.0.0 ... main

2 changed files with 65 additions and 28 deletions

@ -1,4 +1,4 @@
[package]
name = "dropfile"
version = "1.0.0"
edition = "2021"
version = "1.0.3"
edition = "2021"

@ -1,25 +1,27 @@
use std::{fs::{self, File}, io::{self, ErrorKind, IoSlice, Seek, Write}, ops::{Deref, DerefMut}};
use std::{fs::{self, File}, io::{self, ErrorKind, IoSlice, IoSliceMut, Seek, SeekFrom, Read, Write}, ops::{Deref, DerefMut}, path::Path};
pub struct DropFile<'a> {
path: &'a str,
pub struct DropFile {
path: Box<Path>,
file: Option<File>,
created: bool,
written_to: bool,
}
impl<'a> DropFile<'a> {
pub fn open(path: &'a str, create: bool) -> Result<Self, &'static str> {
impl DropFile {
pub fn open<P: AsRef<Path>>(path: P, create: bool) -> Result<Self, &'static str> {
let path = path.as_ref();
let mut file_options = File::options();
file_options.read(true).write(true).create_new(create);
let file = file_options.open(&(path)).map_err(|err| match err.kind() {
let file = file_options.open(path).map_err(|err| match err.kind() {
ErrorKind::AlreadyExists => "file already exists",
_ => "failed to open file"
})?;
return Ok(Self { path, file: Some(file), created: create, written_to: false, });
return Ok(Self { path: path.into(), file: Some(file), created: create, written_to: false, });
}
fn delete_file(&mut self) -> Result<(), &'static str> {
pub fn delete_file(&mut self) -> Result<(), &'static str> {
if self.file.take().is_none() {
return Ok(());
}
@ -32,56 +34,91 @@ impl<'a> DropFile<'a> {
}
pub fn trunc(&mut self) -> Result<(), &'static str> {
let file = self.file.as_mut().ok_or("file deleted")?;
file.rewind().map_err(|_| "failed to rewind file")?;
file.set_len(0).map_err(|_| "failed to truncate file")?;
self.rewind().map_err(|_| "failed to rewind file")?;
self.set_len(0).map_err(|_| "failed to truncate file")?;
self.written_to = true;
return Ok(());
}
pub fn trunc_to_cursor(&mut self) -> Result<(), &'static str> {
let file = self.file.as_mut().ok_or("file deleted")?;
let cursor = file.stream_position().map_err(|_| "failed to get cursor position")?;
file.set_len(cursor).map_err(|_| "failed to truncate file")?;
let cursor = self.stream_position().map_err(|_| "failed to get cursor position")?;
self.set_len(cursor).map_err(|_| "failed to truncate file")?;
self.written_to = true;
return Ok(());
}
pub fn path(&self) -> &'a str {
pub fn write_trunc<T: AsRef<[u8]>>(&mut self, bytes: T) -> Result<usize, &'static str> {
self.rewind().map_err(|_| "failed to rewind")?;
let w = self.write(bytes.as_ref()).map_err(|_| "failed to write file")?;
let w_u64 = w.try_into().map_err(|_| "failed to convert from usize to u64")?;
self.set_len(w_u64).map_err(|_| "failed to truncate file")?;
return Ok(w);
}
pub fn path(&self) -> &Path {
return &(self.path);
}
}
impl Drop for DropFile<'_> {
impl Drop for DropFile {
fn drop(&mut self) {
if self.created && !self.written_to {
self.delete_file().unwrap();
}
}
}
impl Deref for DropFile<'_> {
impl Deref for DropFile {
type Target = fs::File;
fn deref(&self) -> &Self::Target {
return self.file.as_ref().unwrap();
}
}
impl DerefMut for DropFile<'_> {
impl DerefMut for DropFile {
fn deref_mut(&mut self) -> &mut Self::Target {
return self.file.as_mut().unwrap();
}
}
impl Write for DropFile<'_> {
impl Seek for DropFile {
fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
return self.deref_mut().seek(pos);
}
}
impl Read for DropFile {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
return self.deref_mut().read(buf);
}
fn read_vectored(&mut self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
return self.deref_mut().read_vectored(bufs);
}
fn read_to_end(&mut self, buf: &mut Vec<u8>) -> io::Result<usize> {
return self.deref_mut().read_to_end(buf);
}
fn read_to_string(&mut self, buf: &mut String) -> io::Result<usize> {
return self.deref_mut().read_to_string(buf);
}
}
impl Write for DropFile {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
self.written_to = true;
return self.deref_mut().write(buf);
return self.deref_mut().write(buf).map(|w| {
self.written_to = true;
return w;
});
}
fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
self.written_to = true;
return self.deref_mut().write_vectored(bufs);
return self.deref_mut().write_vectored(bufs).map(|w| {
self.written_to = true;
return w;
});
}
fn flush(&mut self) -> io::Result<()> {
self.written_to = true;
return self.deref_mut().flush();
return self.deref_mut().flush().map(|_| {
self.written_to = true;
return ();
});
}
}