override
Source: crates/lvcs-doc/src/kinds/override/mod.rs.
/// An override's id (decisions 71 and 111; `OverrideClaim::id`, its one
/// implementation): the `HASH` of the canonical CBOR array (workspace id,
/// claimant key, base address, path, claim time), the ids and key as byte
/// strings, the base address and path as text, and the claim time as the
/// claiming request's `Origin.time_ms`. Written in `ID_ENCODING`. A workspace
/// actor's claims never overlap (see `Claim`); claims made concurrently on
/// different peers (M3) may, and then the view uses the override with the
/// smaller id, comparing the 32 bytes (not the `ID_ENCODING` text, whose
/// digits sort before its letters).
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Serialize, Deserialize)]
pub struct OverrideId(#[serde(with = "crate::cbor::fixed")] pub [u8; 32]);
/// What part of its base an override replaces in the workspace view.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum OverrideScope {
/// A range of the base document's `/content`, anchored inclusively
/// (decisions 41, 76, and 83): base edits outside it flow through to the
/// view and edits inside it are hidden. [`RangeAnchor::heads`] are the
/// base heads when the range was claimed.
Range(RangeAnchor),
/// The whole base document, whatever it holds, claimed at `base_heads`:
/// every base edit is hidden. A binary file is overridden this way,
/// since it has no ranges (design §3).
Whole {
#[serde(with = "crate::cbor::heads")]
base_heads: Vec<ChangeHash>,
},
/// No base: a file created only in this workspace, a whole-document
/// override with an absent base (decision 71).
Absent,
}
/// The claim an override was created for: written once, by
/// [`OverrideInit`], and never changed.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OverrideClaim {
/// For a `Range` or `Whole` scope, the address of the document that
/// holds the claimed content in the workspace's base view: the `file`
/// document at the path or, in a stacked workspace, an override
/// document of a workspace it stacks on. For `Absent`, the path the
/// file has in the workspace.
pub base: String,
/// The file path the claim resolves to in the workspace (decision 111),
/// set by the workspace that claims it: `base` itself when `base` is the
/// path's file document or the scope is `Absent`, and for a stacked
/// claim the file path of the lower override `base` names, never that
/// override's address. An override change, and the override's index
/// entry, is authorized for `Write` on it (decisions 111 and 112), and
/// every peer accepts a claim only with `base` equal to `path` or
/// naming an override (`OVERRIDE_ADDRESS`).
pub path: String,
pub scope: OverrideScope,
/// Who claimed it; with the workspace id, `base`, `path`, and
/// `time_ms`, an input of the override id.
pub claimant: ParticipantKey,
/// The claiming request's `Origin.time_ms`.
pub time_ms: i64,
}
/// Create an override's content at claim time (design §8): the first event
/// a new override document gets. It is idempotent (decision 97): an override
/// document already holding an equal init (its `/claim` holds `claim`, and
/// the change that wrote it is `origin.author`'s at `origin.time_ms / 1000`
/// seconds and wrote `content` and `executable`, read at that change's
/// heads) commits nothing and renders again, so an init re-sent after a
/// workspace actor's restart is answered by a render. One holding a
/// different init refuses it, and a file document ignores it: the event
/// has no answer, so both write and render nothing.
///
/// Layout: the genesis operations are the `file` kind's, in the same order
/// (`/content` an empty Text, `/meta` a map, then `format` = `text`,
/// `executable` = false, `deleted` = true), so an override document renders,
/// takes `Edit`, `DiskEdit`, `BundleEdit`, `ReadAt`, `WatchAnchors`, and
/// `Claim`, and answers like a file document. The init change, on top of genesis and committed by
/// `origin.author` at `origin.time_ms / 1000` seconds, puts `/claim` as a
/// byte string holding the canonical CBOR encoding of `claim`, then writes
/// `content` and `executable` the way an import does, deleting and
/// re-putting `/meta/format` and `/meta/deleted` (false unless `content` is
/// `Deleted`) (decision 76). `claim.time_ms` is `origin.time_ms`.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OverrideInit {
pub origin: Origin,
pub claim: OverrideClaim,
/// What the base view holds in the claimed scope at claim time: the
/// range's text, or the whole document's body. `Deleted` for an
/// `Absent` scope: its first content comes with the edit or save that
/// created the file.
pub content: FileBody,
pub executable: bool,
}
/// An override document's render, emitted where a file document emits
/// `DocOutput::Rendered`: after every applied change, once for every
/// `DiskEdit`, and on `Render`. `claim` is `None` while the document holds
/// only its genesis change, before its [`OverrideInit`] arrived or synced
/// (or when `/claim` holds no claim's encoding). `after` is as for
/// `DocOutput::Rendered`: the `stamp` of the `DiskEdit` whose handling
/// produced this render, `None` for any other render.
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct OverrideRendered {
#[serde(with = "crate::cbor::heads")]
pub heads: Vec<ChangeHash>,
pub claim: Option<OverrideClaim>,
pub body: FileBody,
pub executable: bool,
pub after: Option<u64>,
}