pub struct Document { /* private fields */ }Expand description
A format-neutral in-memory document: the original source text, its parsed
Value, and the Format both came from. Has no file coupling —
construct it from a string or any std::io::Read the caller supplies,
edit it source-preservingly with set /
unset / add /
remove, and read the result back with
source. DocumentFile is just this plus a path.
Implementations§
Source§impl Document
impl Document
Sourcepub fn parse(source: &str, format: Format) -> DocumentResult<Document>
pub fn parse(source: &str, format: Format) -> DocumentResult<Document>
Parse source in the given format.
Named parse (not from_str) deliberately: this takes an explicit
format argument, so it is not the single-argument std::str::FromStr
contract that from_str would imply.
Sourcepub fn from_reader<R: Read>(
reader: R,
format: Format,
) -> DocumentResult<Document>
pub fn from_reader<R: Read>( reader: R, format: Format, ) -> DocumentResult<Document>
Read reader fully to a String, then parse it in the given
format.
Reads only from the supplied reader — never touches the process’s
own stdin.
Sourcepub fn source(&self) -> &str
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.
Sourcepub fn addressing(&self) -> Addressing<'static>
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.
Sourcepub fn addressing_keyed<'a>(
&self,
keyed_lists: &'a [KeyedList<'a>],
) -> Addressing<'a>
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.
Sourcepub fn value_at(&self, path: &str) -> DocumentResult<Value>
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.
Sourcepub fn value_at_typed(
&self,
path: &str,
expected: ValueType,
) -> DocumentResult<Value>
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.
Sourcepub fn set_typed(
&mut self,
key: &str,
raw: Option<&str>,
value_type: ValueType,
) -> DocumentResult<()>
pub fn set_typed( &mut self, key: &str, raw: Option<&str>, value_type: ValueType, ) -> DocumentResult<()>
Sourcepub fn encode(&self) -> DocumentResult<String>
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§impl Document
impl Document
Sourcepub fn set(&mut self, key: &str, value: Value) -> DocumentResult<()>
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.
Sourcepub fn set_addressed(
&mut self,
key: &str,
value: Value,
addressing: Addressing<'_>,
) -> DocumentResult<()>
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.
Sourcepub fn add(
&mut self,
key: &str,
slug: &str,
slug_field: &str,
fields: &[(String, Value)],
) -> DocumentResult<()>
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.
Sourcepub fn remove(
&mut self,
key: &str,
slug: &str,
slug_field: &str,
) -> DocumentResult<()>
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.
Sourcepub fn unset(&mut self, key: &str) -> DocumentResult<bool>
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.
Sourcepub fn unset_addressed(
&mut self,
key: &str,
addressing: Addressing<'_>,
) -> DocumentResult<bool>
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.