pub struct PluginArtifact { /* private fields */ }Expand description
One file a consumer installs into a harness.
The destination is expressed as components relative to the user’s home
directory rather than an absolute path, for the same reason
crate::launch recipes never pick a location in the user’s home: the crate
states where within a home the harness looks, and the consumer supplies the
home it is installing into — which is also what makes the whole thing
testable against a temporary directory.
Implementations§
Source§impl PluginArtifact
impl PluginArtifact
Sourcepub const fn file_name(&self) -> &'static str
pub const fn file_name(&self) -> &'static str
The file name to write, without any directory part.
Sourcepub const fn install_dir_components(&self) -> &'static [&'static str]
pub const fn install_dir_components(&self) -> &'static [&'static str]
The install directory’s path components, relative to the user’s home.
Exposed so an installer can describe the destination — in a dry run, say — without having a home directory to resolve against.
Sourcepub const fn contents(&self) -> &'static str
pub const fn contents(&self) -> &'static str
The asset’s full contents, embedded at compile time.
Sourcepub fn install_dir(&self, home: &Path) -> PathBuf
pub fn install_dir(&self, home: &Path) -> PathBuf
The directory this artifact installs into, beneath home.
Sourcepub fn install_path(&self, home: &Path) -> PathBuf
pub fn install_path(&self, home: &Path) -> PathBuf
The full path this artifact installs to, beneath home.
Sourcepub const fn superseded_file_names(&self) -> &'static [&'static str]
pub const fn superseded_file_names(&self) -> &'static [&'static str]
File names in this artifact’s own install directory that a previous release of some client wrote, and that installing this artifact must remove.
Only meaningful for a harness that loads a directory rather than a file: there a superseded copy is not merely stale, it is a second reader, and it keeps running the behaviour this artifact replaced. pi is that harness, and its list names a file another client shipped — which is the whole reason the list is crate-owned. A client can be expected to know what it used to install; it cannot be expected to know what its competitor did, and removing only one’s own leaves the collision intact from the other direction.
This is the one place a vendor’s name may appear in this module. It is
not carried into anything installed — it names bytes being deleted, not
bytes being written — and the vendor-neutrality bar on
PluginArtifact::contents is unaffected.
Sourcepub fn superseded_paths(&self, home: &Path) -> Vec<PathBuf>
pub fn superseded_paths(&self, home: &Path) -> Vec<PathBuf>
The paths Self::install removes, beneath home.
Exposed for a consumer that owns its own write path — a content-keyed refresh, say — and needs the removal without the write.
Sourcepub fn install(&self, home: &Path) -> Result<PathBuf>
pub fn install(&self, home: &Path) -> Result<PathBuf>
Write this artifact beneath home, creating its directory and removing
every superseded sibling. Returns the path written.
The removal is not tidiness. A harness that auto-discovers a whole directory loads a superseded copy alongside this one, and two copies of a capture extension in one process destroy each other’s attribution — which means an install that only wrote would leave an upgrading user exactly as broken as before, with the new bytes on disk to prove the fix had shipped. Writing and removing therefore belong to one operation, not to each consumer’s good intentions.
Belonging to one operation is a claim about the failures too, and it constrains the order — because the state that must never be reached is both files present, and writing first reaches it the moment a removal fails. So the bytes are staged first under a name the harness’s glob cannot match, the superseded siblings are removed second, and the staged file is renamed onto its final name last. Each way that can fail leaves at most one extension where the harness looks:
- staging fails — nothing on disk changed;
- a superseded sibling exists and cannot be removed — the staged bytes are discarded and the error returned, so the user is left with the old copy still working rather than with a second reader;
- the rename fails — the superseded copy is gone and the new file never arrived, so capture is off, loudly, instead of on and silently unattributed.
Staging under a non-matching name buys a second thing: a harness reads that directory every time it starts a session, not once when an installer runs, so a session starting mid-write must not be able to find a half-written file spelled like something it loads.
A superseded file that is absent is not an error. One that exists and cannot be removed is: the caller has to know that the harness will still load it, and is better placed than this crate to decide whether that fails the launch or warns.
§Errors
Any I/O failure creating the directory, staging the bytes, removing a superseded sibling that exists, or renaming the staged file into place. An error after staging takes the staged file with it, so a failed install never leaves debris in a directory the harness reads — but a rename that failed has already removed the superseded copies, and the caller is being told that nothing is installed.
Trait Implementations§
Source§impl Clone for PluginArtifact
impl Clone for PluginArtifact
Source§fn clone(&self) -> PluginArtifact
fn clone(&self) -> PluginArtifact
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreimpl Copy for PluginArtifact
Source§impl Debug for PluginArtifact
impl Debug for PluginArtifact
impl Eq for PluginArtifact
Source§impl PartialEq for PluginArtifact
impl PartialEq for PluginArtifact
impl StructuralPartialEq for PluginArtifact
Auto Trait Implementations§
impl Freeze for PluginArtifact
impl RefUnwindSafe for PluginArtifact
impl Send for PluginArtifact
impl Sync for PluginArtifact
impl Unpin for PluginArtifact
impl UnsafeUnpin for PluginArtifact
impl UnwindSafe for PluginArtifact
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
Source§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.