tempfile_fast

Struct Sponge

Source
pub struct Sponge { /* private fields */ }
Expand description

A safer abstraction for atomic overwrites of files.

A Sponge will “soak up” writes, and eventually, when you’re ready, write them to the destination file. This is atomic, so the destination file will never be left in an intermediate state. This is error, panic, and crash safe.

Ownership and permission is preserved, where appropriate for the platform.

Space is needed to soak up these writes: If you are overwriting a large file, you may need disk space for the entire file to be stored twice.

For performance and correctness reasons, many of the things that can go wrong will go wrong at commit() time, not on creation. This might not be what you want if you are doing a very expensive operation. Most of the failures are permissions errors, however. If you are operating as a single user inside the user’s directory, the chance of failure (except for disk space) is negligible.

§Example

let mut temp = tempfile_fast::Sponge::new_for("example.txt").unwrap();
temp.write_all(b"hello").unwrap();
temp.commit().unwrap();

Implementations§

Source§

impl Sponge

Source

pub fn new_for<P: AsRef<Path>>(path: P) -> Result<Sponge, Error>

Create a Sponge which will eventually overwrite the named file. The file does not have to exist.

This will be resolved to an absolute path relative to the current directory immediately.

The path is not run through fs::canonicalize, so other oddities will resolve at commit() time. Notably, a symlink (or hardlink, or reflink) will be converted into a regular file, using the target’s fs::metadata.

Intermediate directories will be created using the platform defaults (e.g. permissions), if this is not what you want, create them in advance.

Source

pub fn commit(self) -> Result<(), Error>

Write the Sponge out to the destination file.

Ownership and permission is preserved, where appropriate for the platform. The permissions and ownership are resolved now, using the (absolute) path provided. i.e. changes to the destination’s file’s permissions since the creation of the Sponge will be included.

The aim is to transfer all ownership and permission information, but not timestamps. The implementation, and what information is transferred, is subject to change in minor versions.

The file is flush()ed correctly, but not fsync()’d. The update is atomic against anything that happens to the current process, including erroring, panicking, or crashing.

If you need the update to survive power loss, or OS/kernel issues, you should additionally follow the platform recommendations for fsync(), which may involve calling fsync() on at least the new file, and probably on the parent directory. Note that this is the same as every other file API, but is being called out here as a reminder, if you are building certain types of application.

§Platform-specific behavior

Metadata:

  • unix (including linux): At least chown(uid, gid) and chmod(mode_t)
  • windows: At least the readonly flag.
  • all: See fs::set_permissions
§Error

If any underlying operation fails the system error will be returned directly. This method consumes self, so these errors are not recoverable. Failing to set the ownership information on the temporary file is an error, not ignored, unlike in many implementations.

Trait Implementations§

Source§

impl Write for Sponge

A Sponge is a BufWriter.

Source§

fn write(&mut self, buf: &[u8]) -> Result<usize, Error>

write to the intermediate file, without touching the destination.

Source§

fn flush(&mut self) -> Result<(), Error>

flush to the intermediate file, without touching the destination. This has no real purpose, as these writes should not be observable.

1.36.0 · Source§

fn write_vectored(&mut self, bufs: &[IoSlice<'_>]) -> Result<usize, Error>

Like write, except that it writes from a slice of buffers. Read more
Source§

fn is_write_vectored(&self) -> bool

🔬This is a nightly-only experimental API. (can_vector)
Determines if this Writer has an efficient write_vectored implementation. Read more
1.0.0 · Source§

fn write_all(&mut self, buf: &[u8]) -> Result<(), Error>

Attempts to write an entire buffer into this writer. Read more
Source§

fn write_all_vectored(&mut self, bufs: &mut [IoSlice<'_>]) -> Result<(), Error>

🔬This is a nightly-only experimental API. (write_all_vectored)
Attempts to write multiple buffers into this writer. Read more
1.0.0 · Source§

fn write_fmt(&mut self, fmt: Arguments<'_>) -> Result<(), Error>

Writes a formatted string into this writer, returning any error encountered. Read more
1.0.0 · Source§

fn by_ref(&mut self) -> &mut Self
where Self: Sized,

Creates a “by reference” adapter for this instance of Write. Read more

Auto Trait Implementations§

§

impl Freeze for Sponge

§

impl RefUnwindSafe for Sponge

§

impl Send for Sponge

§

impl Sync for Sponge

§

impl Unpin for Sponge

§

impl UnwindSafe for Sponge

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V