pub struct Document {
rev: Rev,
stamp: DocStamp,
ids: Allocator,
content: Content,
}Expand description
Authored state only — the derived index is built beside it
(DocIndex). The document is the implicit root of the
containment tree: not an element, cannot be deleted, moved, or raced.
Blocks whose parent is Id::NULL live at document level.
Serializing a document writes its Content and nothing else, and
parsing one goes through From<Content>, which is
what keeps a document read off a file stamped and marked like one that
was folded.
Fields§
§rev: RevThe head position in the log: the rev of the last commit folded in.
Minted only by a successful Document::try_apply, so a refused
commit consumes no rev and the log cannot gap.
stamp: DocStampNames this value, not this position: two documents at one rev in
two processes are unrelated. Minted wherever a distinct value is
born — a successful fold, an empty document, a parsed file — and
carried by Clone.
ids: AllocatorWhere the next id of each kind comes from. Derived, never stored:
Self::try_apply raises a mark for every entity a commit names,
deleted ones included, so folding a log leaves the marks past
everything the document has ever held — which is why undoing a
delete can re-create the entity under its own id and why a deleted
id cannot come back on a different one. A document read off a file
has no such history, so its marks come from what it holds.
content: ContentImplementations§
Source§impl Document
impl Document
Sourcepub fn rev(&self) -> Rev
pub fn rev(&self) -> Rev
The log position this document holds: the rev of the last commit
the Repo folded into it.
Sourcepub fn stamp(&self) -> DocStamp
pub fn stamp(&self) -> DocStamp
Names this value: the gate every derived cache beside the document
re-checks before rebuilding, DocIndex included.
Sourcepub(crate) fn restored_at(&mut self, rev: Rev, reached: &Document)
pub(crate) fn restored_at(&mut self, rev: Rev, reached: &Document)
Take this value as the document at rev, in a session that has
already got as far as reached: the position it is being adopted
at, a stamp of its own since it is a distinct value in this
process, and the one thing a session accumulates rather than holds
— the allocator’s marks — carried over from where it had got to.
A mark never falls, here or in the fold: an id a taken-back edit minted is never minted again, which is what stops a restored entity’s id being handed out a second time.
Payloads are not carried. They live in the store, addressed by content and never deleted, so a rev that references one gets it back when it is read — and a rev that references none holds none, live or reopened.
The door a history step comes through (docs/log-vs-snapshot.md),
and the only way a rev moves without a fold.
Sourcepub fn positioned_at(&mut self, rev: Rev)
pub fn positioned_at(&mut self, rev: Rev)
Take this value as the document at rev — a rev file names its
position in its own name, never inside itself, so the reader is what
puts the two together.
Sourcepub fn mint<K: IdKind>(&mut self) -> Id<K>
pub fn mint<K: IdKind>(&mut self) -> Id<K>
A fresh id of this document’s own, for a caller with no gesture to mint through — the fold’s own high-water mark advanced by one.
pub fn title_block(&self) -> &TitleBlock
pub fn block(&self, id: &BlockId) -> Option<&Block>
pub fn blocks(&self) -> impl Iterator<Item = (BlockId, &Block)>
pub fn pin(&self, id: &PinId) -> Option<&Pin>
pub fn pins(&self) -> impl Iterator<Item = (PinId, &Pin)>
pub fn route(&self, id: &RouteId) -> Option<&Route>
pub fn routes(&self) -> impl Iterator<Item = (RouteId, &Route)>
pub fn route_label(&self, id: &RouteLabelId) -> Option<&RouteLabel>
pub fn route_labels(&self) -> impl Iterator<Item = (RouteLabelId, &RouteLabel)>
pub fn text(&self, id: &TextId) -> Option<&Text>
pub fn texts(&self) -> impl Iterator<Item = (TextId, &Text)>
pub fn area(&self, id: &AreaId) -> Option<&Area>
pub fn areas(&self) -> impl Iterator<Item = (AreaId, &Area)>
pub fn image(&self, id: &ImageId) -> Option<&Image>
pub fn images(&self) -> impl Iterator<Item = (ImageId, &Image)>
Sourcepub fn assets(&self) -> impl Iterator<Item = (AssetHash, &Asset)>
pub fn assets(&self) -> impl Iterator<Item = (AssetHash, &Asset)>
Every payload the document holds, in hash order. Assets are create-only, so this is simply what is there.
pub fn try_apply(&self, commit: &Commit) -> Result<Document, FoldError>
fn no_block_cycles(&self, id: BlockId) -> bool
Sourcefn validate_block_owner(&self, id: BlockId) -> Result<(), FoldError>
fn validate_block_owner(&self, id: BlockId) -> Result<(), FoldError>
A commit that removed its target leaves nothing to check here:
apply refuses an op whose target was absent to begin with, so
a missing entity at this point is one this very commit deleted.
Sourcefn holds_scope(&self, scope: BlockId) -> bool
fn holds_scope(&self, scope: BlockId) -> bool
The document root is a scope like any other: Id::NULL names it,
holds scoped entities, and is not a block — so it is never in the
map and never needs to be.
fn validate_pin_owner(&self, id: PinId) -> Result<(), FoldError>
fn validate_route_owner_and_endpoints( &self, id: RouteId, ) -> Result<(), FoldError>
fn validate_route_label_owner(&self, id: RouteLabelId) -> Result<(), FoldError>
fn validate_text_owner(&self, id: TextId) -> Result<(), FoldError>
fn validate_area_owner(&self, id: AreaId) -> Result<(), FoldError>
fn validate_image_owner(&self, id: ImageId) -> Result<(), FoldError>
Sourcefn observe_own_ids(&mut self)
fn observe_own_ids(&mut self)
Every mark this document’s own content implies. A fold raises the marks as it goes; a document read off a file has only what it holds, which is why a parse goes through here.
Sourcepub fn creating_commit(&self, label: &str) -> Option<Commit>
pub fn creating_commit(&self, label: &str) -> Option<Commit>
The whole document as one labeled commit of creates, in dependency
order — the one bridge from a parsed file to the log that builds
it. Id-preserving: the ids in the file are the ids, and re-minting
on paste into a populated document is
edit::clipboard’s
job, not a loader’s. None for a document with nothing in it.
Sourcepub fn referenced_assets(&self) -> BTreeSet<AssetHash>
pub fn referenced_assets(&self) -> BTreeSet<AssetHash>
Every payload this document references: the artwork behind its icons and its images. Never the table’s own keys — a payload outlives the reference that brought it in, so the table can hold bytes nothing points at.
Sourcepub fn without_assets(&self) -> Document
pub fn without_assets(&self) -> Document
This value with its payloads left behind — what a rev file is
written from (docs/log-vs-snapshot.md §10). assets/ is the one
home for bytes, so a rev carries the references and the
content-addressed store carries what they name; the entity tables
are Arcs, so the clone is pointers.
Sourcepub fn attach_assets<E>(
&mut self,
payload: impl FnMut(AssetHash) -> Result<Asset, E>,
) -> Result<(), E>
pub fn attach_assets<E>( &mut self, payload: impl FnMut(AssetHash) -> Result<Asset, E>, ) -> Result<(), E>
Put back every payload this document references, asking payload
for the bytes behind each hash — Self::without_assets’s other
half.
§Errors
Whatever the source says about the first payload it will not hand back.