Struct RecordId
pub struct RecordId(/* private fields */);Expand description
The stable identity of a record. Encoded by prefix:
file-record:<uuid> (a file, by the durable id its filesystem record
carries — see RecordId::identify_file), file:<absolute path> (a
file known only by where it is: a not-yet-written Save As target, or a
filesystem that can’t hold the durable id), uuid:<uuid> (minted, for a
record with no natural name), tab:<tab id> (a window’s scratch document
until a file names it, see RecordId::for_tab) and
derived:<role>@<id> (see RecordId::derived).
§Files
A file’s identity is its file record, never its path or its bytes:
- Rename and move keep it. The collaborative filesystem keys files by
a
FileRecordIdthat survives rename and move and serves it as theuser.tilo.record-idattribute; elsewhere the same attribute is written once on first open and travels with the inode. - A copy is a new file. The filesystem mints a new record for a
created file, and a plain local copy does not carry the attribute, so a
copy starts with its own records. That is deliberate: copying is how a
person forks a document — to send a clean version, or to try different
edits — and mirroring every note into the copy would surprise them and
leak notes into what they hand on. Tools asked to preserve extended
attributes (
cp -a,rsync -X) are an explicit request to keep the identity, and do. - Identical bytes are not the same file. Nothing here is derived from
content, so two files with the same bytes never share edits by accident.
Content that should be shared by bytes is a blob reference instead
(
add_blob_reference).
The prefix is part of the id, not a tag beside it: the id travels on the wire and names a file on disk, so it must be self-describing.
Implementations§
§impl RecordId
impl RecordId
pub fn package_primary() -> RecordId
pub fn package_primary() -> RecordId
Internal custody key for a package’s existing room-primary document. It never travels as a record id on the collaboration wire.
pub fn is_package_primary(&self) -> bool
pub fn for_file(path: impl AsRef<Path>) -> RecordId
pub fn for_file(path: impl AsRef<Path>) -> RecordId
The record a file is. Relative paths resolve against the cwd, so two spellings of one file are one record.
The id embeds the absolute path, so two peers reach one record only if the file sits at the same path on both. Don’t use this for content embedded in a document (a dropped image) — that needs a content-addressed record, not a path-addressed one.
pub fn for_file_record(id: Uuid) -> RecordId
pub fn for_file_record(id: Uuid) -> RecordId
The record of the file whose filesystem record id is id — the
collaborative filesystem’s FileRecordId, or the id
Self::identify_file wrote for a file elsewhere.
pub fn identify_file(path: impl AsRef<Path>) -> RecordId
pub fn identify_file(path: impl AsRef<Path>) -> RecordId
The durable identity of the file at path, so reopening it after a
rename or move reaches the same records.
Reads the file’s user.tilo.record-id attribute (16 raw bytes — the
collaborative filesystem serves its FileRecordId there; on macOS,
where every copy inherits the attribute, the id is followed by the
inode it belongs to so a copy is told apart). A file
without one, on a filesystem that accepts user attributes, gets a
freshly minted id written with create-only semantics (a concurrent
opener that wins the race is re-read, so both agree). Anything else —
no attribute support, a read-only file, not a regular file — falls
back to the path identity Self::for_file: the best identity the
file can carry.
Two system calls at most besides the metadata lookup; call it off the UI thread when the file might be on a network filesystem.
pub fn minted() -> RecordId
pub fn for_tab(tab: u64) -> RecordId
pub fn for_tab(tab: u64) -> RecordId
Reuses the tab id rather than minting a new one: it’s already unique per machine and persisted with the window tree, so a separate id beside it could only drift.
pub fn room_default() -> RecordId
pub fn room_default() -> RecordId
The record an app opens in a room when nothing names another one: the first window of the app on any device of the room, native or browser, so they all meet on one document. Constant, so every device derives the same id without asking; the room scopes it.
pub fn derived(role: &str, of: &RecordId) -> RecordId
pub fn derived(role: &str, of: &RecordId) -> RecordId
Identity of the record that plays role for of — “the annotations
of this document”. Distinct from its target so the two can be
shared separately: handing over the document doesn’t hand the notes.
pub fn parse(s: &str) -> Option<RecordId>
pub fn parse(s: &str) -> Option<RecordId>
Adopt an id read back from a document, a room index, or the wire. Invalid, oversized, or non-canonical names fail closed: IDs name collaboration routes and storage directories, so accepting arbitrary strings here would turn a room index into an allocation oracle.
pub fn uri(&self) -> String
pub fn uri(&self) -> String
The URI asking an app to open this record
([collab_types::RECORD_URI_SCHEME]).
pub fn as_str(&self) -> &str
pub fn file_record(&self) -> Option<Uuid>
pub fn file_record(&self) -> Option<Uuid>
The filesystem record id of a file-record: identity.
pub fn storage_key(&self) -> String
pub fn storage_key(&self) -> String
A filesystem-safe directory name for this record’s document. Must be stable (same record → same directory next launch, or data is silently orphaned) and collision-free (two records sharing a directory merge their documents) — hence a readable sanitised prefix plus a hash of the whole id, which is what actually distinguishes them.
Trait Implementations§
§impl Ord for RecordId
impl Ord for RecordId
1.21.0 (const: unstable) · Source§fn max(self, other: Self) -> Selfwhere
Self: Sized,
fn max(self, other: Self) -> Selfwhere
Self: Sized,
§impl PartialOrd for RecordId
impl PartialOrd for RecordId
impl Eq for RecordId
impl StructuralPartialEq for RecordId
Auto Trait Implementations§
impl Freeze for RecordId
impl RefUnwindSafe for RecordId
impl Send for RecordId
impl Sync for RecordId
impl Unpin for RecordId
impl UnsafeUnpin for RecordId
impl UnwindSafe for RecordId
Blanket Implementations§
§impl<T> AnyEq for T
impl<T> AnyEq for T
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,
§impl<Q, K> Comparable<K> for Q
impl<Q, K> Comparable<K> for Q
§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can
then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be
further downcast into Rc<ConcreteType> where ConcreteType implements Trait.§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &Any’s vtable from &Trait’s.§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot
generate &mut Any’s vtable from &mut Trait’s.§impl<T> DowncastSync for T
impl<T> DowncastSync for T
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key and return true if they are equal.§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more