pub struct ChangeSet { /* private fields */ }Expand description
A set of writes staged as one unit, applied all-or-nothing by
apply.
Built by the mutation ops as they compute their edits, and applied once at
the end. Ops execute in the order they were staged: a set is a sequence,
not a bag, because rename-then-write and remove-then-rewrite-the-parent
depend on it.
Implementations§
Source§impl ChangeSet
impl ChangeSet
Sourcepub fn write(
&mut self,
path: impl Into<PathBuf>,
contents: impl Into<Vec<u8>>,
) -> &mut Self
pub fn write( &mut self, path: impl Into<PathBuf>, contents: impl Into<Vec<u8>>, ) -> &mut Self
Stage a write of contents to path (root-relative).
Sourcepub fn rename(
&mut self,
from: impl Into<PathBuf>,
to: impl Into<PathBuf>,
) -> &mut Self
pub fn rename( &mut self, from: impl Into<PathBuf>, to: impl Into<PathBuf>, ) -> &mut Self
Stage a move from from to to (both root-relative).
Sourcepub fn remove(&mut self, path: impl Into<PathBuf>) -> &mut Self
pub fn remove(&mut self, path: impl Into<PathBuf>) -> &mut Self
Stage the removal of path (root-relative).
Sourcepub fn copy_from(
&mut self,
path: impl Into<PathBuf>,
source: impl Into<PathBuf>,
) -> &mut Self
pub fn copy_from( &mut self, path: impl Into<PathBuf>, source: impl Into<PathBuf>, ) -> &mut Self
Stage a copy of the file at source to path (both root-relative),
instead of carrying its bytes through the set.
See FileOp::CopyFrom for the immutability the source has to satisfy —
it is what keeps crash recovery deterministic.
Sourcepub fn set_executable(
&mut self,
path: impl Into<PathBuf>,
executable: bool,
) -> &mut Self
pub fn set_executable( &mut self, path: impl Into<PathBuf>, executable: bool, ) -> &mut Self
Stage making the file at path (root-relative) runnable, or not.
Sourcepub fn set_link(
&mut self,
path: impl Into<PathBuf>,
target: impl Into<PathBuf>,
) -> &mut Self
pub fn set_link( &mut self, path: impl Into<PathBuf>, target: impl Into<PathBuf>, ) -> &mut Self
Stage a symbolic link at path (root-relative) pointing at target,
replacing whatever is there.
See FileOp::SetLink for what the target is and is not: recorded,
never resolved, and not a door for other ops in the set to write
through.
Sourcepub fn expect(
&mut self,
path: impl Into<PathBuf>,
contents: impl Into<Vec<u8>>,
) -> &mut Self
pub fn expect( &mut self, path: impl Into<PathBuf>, contents: impl Into<Vec<u8>>, ) -> &mut Self
Expect path (root-relative) to hold exactly contents when the set
applies — the bytes the caller read when it computed this set.
Checked before the commit point; a mismatch (including the file being
gone) refuses the whole set with Error::Drifted and nothing is
written. See the module docs for when
expectations are checked and what they do and do not guard against.
Sourcepub fn expect_absent(&mut self, path: impl Into<PathBuf>) -> &mut Self
pub fn expect_absent(&mut self, path: impl Into<PathBuf>) -> &mut Self
Expect nothing to be at path (root-relative) when the set applies —
the guard for a create that must not overwrite what a racing writer
put there first.
An expectation speaks of the tree before the set runs, so expecting a path absent and then writing that same path is the ordinary use, not a contradiction.
Sourcepub fn expected(&self) -> &[(PathBuf, Expected)]
pub fn expected(&self) -> &[(PathBuf, Expected)]
The staged expectations, in the order staged — the dry-run view’s other half: what the set demands of the tree, next to what it does to it.
Sourcepub fn staged(&self, path: &Path) -> Option<&[u8]>
pub fn staged(&self, path: &Path) -> Option<&[u8]>
The bytes this set will leave at path, if it writes it — the last
write staged, since a later one supersedes an earlier.
This is what makes a set safe to read back mid-build. A document can be
touched twice by one op (reparent repoints a child that is somehow its
own old parent, and must then edit the text it just staged rather than the
stale copy on disk), and before staging existed the second edit read the
first one’s write off the filesystem. Nothing hits the filesystem now
until commit, so the set has to answer instead.
None if the set does not write path — including when it renames or
removes it, and including a FileOp::CopyFrom, whose bytes are on disk
at the source rather than held in the set. This is deliberately a lookup,
not a filesystem overlay: it resolves the one hazard staging introduces and
nothing more. A caller that must read back a path it staged a copy to has
to read the source itself.
Sourcepub fn renamed_to(&self, path: &Path) -> Option<PathBuf>
pub fn renamed_to(&self, path: &Path) -> Option<PathBuf>
Where this set moves path to, if it moves it — following a chain of
renames to the final destination. None if the set leaves it where it is.
The companion to staged for anything holding a path this
set might move out from under it. The registry is exactly that: it knows
which document it persists into, and a set that renames that document has
to be followed, or its write lands at a path the set just emptied.
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Whether nothing is staged — no ops and no
expectations — so apply would be
a no-op.
Sourcepub fn extend(&mut self, other: ChangeSet) -> &mut Self
pub fn extend(&mut self, other: ChangeSet) -> &mut Self
Append other’s ops after this set’s, consuming it. Its expectations
come along too — they still speak of the pre-apply tree, exactly as
they did in the set that staged them.
Sourcepub async fn apply<FS: Storage>(&self, fs: &FS, root: &Path) -> Result<()>
pub async fn apply<FS: Storage>(&self, fs: &FS, root: &Path) -> Result<()>
Execute every staged op against fs, rooted at root, as one unit —
crash-atomically, behind the default
write-ahead journal.
Shorthand for Journal::default().apply(..); reach
for a named Journal when the default file name would collide with
something the tree already means. Whichever is used here, the same one
has to be used to recover an interruption of it.