Skip to main content

DocumentFile

Struct DocumentFile 

Source
pub struct DocumentFile { /* private fields */ }
Expand description

A file-backed Document: the in-memory document plus the path it was read from.

All reads and source-preserving edits come from Document through [Deref]/[DerefMut]; DocumentFile adds only the file boundary — reading on open and an atomic, symlink-guarded commit on save / edit.

Implementations§

Source§

impl DocumentFile

Source

pub fn open( path: impl AsRef<Path>, format_override: Option<Format>, ) -> DocumentResult<DocumentFile>

Open and parse path.

format_override takes precedence; otherwise the format is detected from the file extension via Format::detect. Reading is always allowed — this does not run the mutation guard.

Source

pub fn open_capped( path: impl AsRef<Path>, format_override: Option<Format>, max_bytes: u64, ) -> DocumentResult<DocumentFile>

Open and parse path like DocumentFile::open, but first reject any non-regular file, or any file larger than max_bytes, without reading its contents.

Use this over open when reading untrusted or secret-bearing config, where an unbounded read of an arbitrary path is a denial-of-service risk.

Source

pub fn path(&self) -> &Path

The file path this document was opened from.

Source

pub fn ensure_mutable(&self, operation: &str) -> DocumentResult<()>

Preflight-check that this document format is writable and this file is safe to mutate — not a symlink, and on unix not hardlinked — without performing any write.

save runs this same guard before it writes, so calling it directly is only useful to front-run a separate side effect with the same guarantee — e.g. a CLI reading a secret from stdin for a set should refuse an unsafe target before consuming that input.

Source§

impl DocumentFile

Source

pub fn edit<F>(&mut self, edit: F) -> DocumentResult<()>
where F: FnOnce(&mut Document) -> DocumentResult<()>,

Run edit against the in-memory Document, then commit once with save. The single-call form of stage-then-save: the edits either all land (on Ok) or none reach disk (on Err, nothing is written), and the commit can’t be forgotten.

Source

pub fn save(&self) -> DocumentResult<()>

Persist the document — every edit staged since open — to its path in a single atomic write.

The mutation verbs (set/unset/add/remove) stage their source-preserving edit in memory and do not touch disk; this is the one commit point. That lets a caller apply several edits and inspect the result via value (e.g. deserialize-and-validate) before any bytes are written, and makes a multi-edit change atomic — all edits land together or none do.

Methods from Deref<Target = Document>§

Source

pub fn value(&self) -> &Value

Borrow the parsed value (reflects the last successful edit).

Source

pub fn source(&self) -> &str

Borrow the current source text — the original bytes with every source-preserving edit applied. This is what DocumentFile::save writes.

Source

pub fn format(&self) -> Format

The format this document was parsed from.

Source

pub fn addressing(&self) -> Addressing<'static>

How a non-numeric path segment resolves against an array in this document: whatever its format declares (see Format::array_rule), with no caller-declared keyed lists.

Use addressing_keyed to add those.

Source

pub fn addressing_keyed<'a>( &self, keyed_lists: &'a [KeyedList<'a>], ) -> Addressing<'a>

addressing plus the caller’s keyed lists, which take precedence over the format rule for the arrays they name.

Source

pub fn value_at(&self, path: &str) -> DocumentResult<Value>

Resolve a dotted path against the parsed document and return the value at that address.

A non-empty ASCII-decimal segment against an array is an index; anything else goes through the format’s own rule, so a Markdown document answers h2.look while a JSON one refuses deps.foo. See addressing.

Source

pub fn value_at_typed( &self, path: &str, expected: ValueType, ) -> DocumentResult<Value>

value_at that also asserts the value at path satisfies expected, returning a DocumentError::TypeMismatch otherwise.

Source

pub fn set_typed( &mut self, key: &str, raw: Option<&str>, value_type: ValueType, ) -> DocumentResult<()>

Build a value from the CLI string raw per an explicit ValueType and set it.

Source

pub fn encode(&self) -> DocumentResult<String>

Re-render the current value in its format via Format::save.

This is a fresh, non-source-preserving render: comments and original formatting are not retained. Use source after source-preserving edits to keep the original formatting.

Source

pub fn set(&mut self, key: &str, value: Value) -> DocumentResult<()>

Set key to the typed value, preserving the rest of the source document. The edit is staged in memory — call save to persist it.

Backend capability mirrors crate::document::set_path where the source editor allows it: the JSON backend replaces an existing value (scalar or collection) and creates missing intermediate parent objects; the TOML backend creates missing parent tables. Backends that cannot express an edit source-preserving (e.g. YAML collection mutation) return DocumentError::UnsupportedOperation.

Source

pub fn set_addressed( &mut self, key: &str, value: Value, addressing: Addressing<'_>, ) -> DocumentResult<()>

set with the caller’s own addressing, so a path that names an array element by its content — identities.me.email — can be written and not merely read.

The address is canonicalized to indices first (see crate::document::resolve_path); everything below this point, the source-preserving backends included, sees only identities.0.email.

Source

pub fn add( &mut self, key: &str, slug: &str, slug_field: &str, fields: &[(String, Value)], ) -> DocumentResult<()>

Add a new element to the keyed list at key, identified by slug/slug_field, with the given fields. Preserves the rest of the source document. An empty key targets the document root when the root is itself the keyed array.

Only JSON and YAML backends implement a source-preserving keyed-collection editor today; other formats return DocumentError::UnsupportedOperation.

Source

pub fn remove( &mut self, key: &str, slug: &str, slug_field: &str, ) -> DocumentResult<()>

Remove the element identified by slug/slug_field from the keyed list at key. Preserves the rest of the source document. An empty key targets the document root when the root is itself the keyed array.

Only JSON and YAML backends implement a source-preserving keyed-collection editor today; other formats return DocumentError::UnsupportedOperation.

Source

pub fn unset(&mut self, key: &str) -> DocumentResult<bool>

Remove the entry at key entirely, preserving the rest of the source document. The edit is staged in memory — call DocumentFile::save to persist it.

Idempotent, like HashSet::remove: returns Ok(false) when there was nothing at key to remove (nothing is staged), and Ok(true) when it was removed.

“Nothing there” does not depend on how deep the path is. A missing leaf and a missing ancestor are the same fact — a.b.c is absent whether a.b exists or not — so both answer Ok(false). Only a path that is malformed stays an error: bad syntax, an index into a non-array, or a segment that tries to traverse through a scalar. Those describe a caller asking something incoherent, not a document that already lacks the key.

A read-only format is the one case that errors before the idempotent answer: “nothing to remove” would report success for a document this verb can never edit.

A content-addressed segment that matches no element is also an error (DocumentError::SlugNotFound), not Ok(false). It is not the same fact as an absent key: the caller named an element and the document has none by that name, which is how a mistyped slug looks, and answering “removed nothing, all good” would swallow it.

Source

pub fn unset_addressed( &mut self, key: &str, addressing: Addressing<'_>, ) -> DocumentResult<bool>

unset with the caller’s own addressing, so an element named by its content can be removed and not merely read. See set_addressed for why the address is canonicalized before anything below sees it.

Trait Implementations§

Source§

impl Clone for DocumentFile

Source§

fn clone(&self) -> DocumentFile

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 Debug for DocumentFile

Source§

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

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

impl Deref for DocumentFile

Source§

type Target = Document

The resulting type after dereferencing.
Source§

fn deref(&self) -> &Document

Dereferences the value.
Source§

impl DerefMut for DocumentFile

Source§

fn deref_mut(&mut self) -> &mut Document

Mutably dereferences the value.

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<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<P, T> Receiver for P
where P: Deref<Target = T> + ?Sized, T: ?Sized,

Source§

type Target = T

🔬This is a nightly-only experimental API. (arbitrary_self_types)
The target type on which the method may be called.
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