Skip to main content

PluginArtifact

Struct PluginArtifact 

Source
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

Source

pub const fn file_name(&self) -> &'static str

The file name to write, without any directory part.

Source

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.

Source

pub const fn contents(&self) -> &'static str

The asset’s full contents, embedded at compile time.

Source

pub fn install_dir(&self, home: &Path) -> PathBuf

The directory this artifact installs into, beneath home.

Source

pub fn install_path(&self, home: &Path) -> PathBuf

The full path this artifact installs to, beneath home.

Source

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.

Source

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.

Source

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

Source§

fn clone(&self) -> PluginArtifact

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 Copy for PluginArtifact

Source§

impl Debug for PluginArtifact

Source§

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

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

impl Eq for PluginArtifact

Source§

impl PartialEq for PluginArtifact

Source§

fn eq(&self, other: &PluginArtifact) -> 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 PluginArtifact

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<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Checks if this value is equivalent to the given key. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
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 = 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<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more