Skip to main content

FileOp

Enum FileOp 

Source
pub enum FileOp {
    Write {
        path: PathBuf,
        bytes: Vec<u8>,
    },
    Rename {
        from: PathBuf,
        to: PathBuf,
    },
    Remove {
        path: PathBuf,
    },
    CopyFrom {
        path: PathBuf,
        source: PathBuf,
    },
    SetExecutable {
        path: PathBuf,
        executable: bool,
    },
    SetLink {
        path: PathBuf,
        target: PathBuf,
    },
}
Expand description

One staged filesystem operation. Paths are root-relative — the root is joined on at apply time, so a set is portable between trees and prints readably in a dry run.

Variants§

§

Write

Write bytes to path, creating it (and any missing parent directory) or replacing it wholesale.

Fields

§path: PathBuf

The file to write.

§bytes: Vec<u8>

Its full new contents.

§

Rename

Move from to to, creating any missing parent directory of to.

Fields

§from: PathBuf

The current path.

§to: PathBuf

The new path.

§

Remove

Remove the file at path. It must exist.

Fields

§path: PathBuf

The file to remove.

§

CopyFrom

Copy the bytes already on disk at source to path, verbatim.

Write with the payload left where it lies. The journal records the source path instead of the bytes, so a set that writes a large payload costs O(path) of journal rather than a second copy of every byte — which is what makes putting a whole captured tree back tractable, where Write would duplicate every byte of it into the journal at the commit point.

The source must be immutable for the lifetime of the change, because that is the entire correctness argument. A Write journals the exact bytes it intends, so replay after a crash is deterministic by construction; a CopyFrom journals a reference, and replay is deterministic only if the referent cannot have changed underneath it. A content-addressed blob satisfies this by definition — its path is the digest of its contents, so bytes found there are the bytes intended, or the file is gone and replay fails loudly. Do not point this at a mutable file, at a path some other op in the same set writes, or at anything outside the root.

This bounds journal growth, not peak memory: rollback still buffers the bytes it overwrites, exactly as Write does.

Fields

§path: PathBuf

The file to write.

§source: PathBuf

The root-relative file to copy from — immutable, and ideally content-addressed.

§

SetExecutable

Make the file at path runnable, or not — one bit, not a mode.

Lands through Storage::set_executable, whose default is the honest no-op for a backend with no such bit: over such a backend the op “applies” as nothing, which is the same nothing the bit’s absence already means there. Undo is captured through ReadStorage::executable, so a bit that was already in the requested state rolls back to itself rather than to its opposite.

A path holding a symbolic link is refused (InvalidInput), whoever made the link: mode writes follow links, so the bit would land on the link’s referent — wherever it points, the lexical root guard notwithstanding.

Fields

§path: PathBuf

The file whose execute bit is set or cleared.

§executable: bool

Whether the file should be runnable afterwards.

Place a symbolic link at path pointing at target, replacing whatever is there.

The target is recorded, never resolved: it may point outside the root, at nothing, or at another link, and staging it writes nothing through it — the same terms as Storage::set_link. What is not permitted is another op in the same set addressing a path that traverses this link: the root guard is lexical, and a set that writes through its own fresh link is writing wherever the link points.

Over a backend that models no links the op is refused (Unsupported) and the set unwinds: unlike an execute bit, a link has no honest substitute.

Fields

§path: PathBuf

Where the link itself lives.

§target: PathBuf

What it points at — recorded as given.

Implementations§

Source§

impl FileOp

Source

pub fn path(&self) -> &Path

The path this op ultimately affects — the destination for a write or a rename, the victim for a remove. What a dry run lists.

Trait Implementations§

Source§

impl Clone for FileOp

Source§

fn clone(&self) -> FileOp

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for FileOp

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Eq for FileOp

Source§

impl PartialEq for FileOp

Source§

fn eq(&self, other: &FileOp) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for FileOp

Auto Trait Implementations§

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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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.