Skip to main content

Document

Struct Document 

Source
pub struct Document<'src> { /* private fields */ }
Expand description

A lossless document interpreted under one explicit literal syntax configuration.

Implementations§

Source§

impl Document<'_>

Source

pub fn compare<'a>(&'a self, other: &'a Document<'_>) -> Comparison

Compare effective declarations by key.

Each side contributes only declarations that participate in lookup. Duplicate resolution uses the document’s own Duplicates policy. A bare declaration, an assigned empty value and an absent key are distinct states; decoded values are compared literally. Export differences are reported only when state and value are otherwise equal.

§Examples
use adotenv::{parse_strict, DifferenceKind};

let left = parse_strict("A=1\nB=\nC=3\n").unwrap();
let right = parse_strict("A=2\nB\nD=4\n").unwrap();
let comparison = left.compare(&right);
let kinds: Vec<_> = comparison
    .differences()
    .iter()
    .map(|entry| (entry.key.as_str(), entry.kind))
    .collect();
assert_eq!(
    kinds,
    [
        ("A", DifferenceKind::Value),
        ("B", DifferenceKind::State),
        ("C", DifferenceKind::OnlyLeft),
        ("D", DifferenceKind::OnlyRight),
    ]
);
Source§

impl Document<'_>

Source

pub fn edit(&self, operations: &[Edit<'_>]) -> Result<VerifiedEdits, EditError>

Plan and verify an entire snapshot-local batch atomically.

§Errors

Invalid selectors, conflicting operations and unintended reparsing are rejected.

Source

pub fn set(&self, key: &str, value: &str) -> Result<VerifiedEdits, EditError>

Set a uniquely named declaration’s exact literal value.

§Errors

Returns a selector, encoding or verification error.

Source

pub fn remove(&self, key: &str) -> Result<VerifiedEdits, EditError>

Remove a uniquely named declaration, not its neighboring comments.

§Errors

Returns a selector or verification error.

Source

pub fn rename( &self, key: &str, new_key: &str, ) -> Result<VerifiedEdits, EditError>

Rename a uniquely named declaration.

§Errors

Returns a selector, key, collision or verification error.

Source

pub fn insert( &self, key: &str, value: Option<&str>, position: InsertPosition<'_>, ) -> Result<VerifiedEdits, EditError>

Insert an assigned or bare declaration.

§Errors

Returns a selector, key, encoding or verification error.

Source

pub fn comment(&self, key: &str) -> Result<VerifiedEdits, EditError>

Comment every physical line of a uniquely named declaration.

§Errors

Returns a selector or verification error.

Source

pub fn uncomment(&self, item: usize) -> Result<VerifiedEdits, EditError>

Uncomment an explicitly selected comment item.

§Errors

Returns a target or verification error. Multiline restoration may require a batch.

Source

pub fn set_export( &self, key: &str, enabled: bool, ) -> Result<VerifiedEdits, EditError>

Enable or disable export on a uniquely named declaration.

§Errors

Returns a selector or verification error.

Source§

impl Document<'_>

Source

pub fn example(&self) -> String

Generate a new example text with every assigned value removed.

Whole-line comments, blank lines, keys, export prefixes, spacing, line endings and the BOM are retained. Bare declarations remain bare. Assigned values become Empty; an empty quoted placeholder keeps an inline comment attached when the grammar requires a value body before it. Invalid or ignored statements, and entries with an empty key, become indentation-preserving # comments so their raw text cannot leak a value. No expansion, environment access or I/O is performed.

§Panics

Panics only if an internal document-snapshot invariant is broken; an Entry item always has an entry view.

§Examples
use adotenv::parse;

let source = "# app\nA=1\nB=\"x\" # note\nBARE\nBAD KEY=secret\n";
let (doc, _) = parse(source);
let example = doc.example();
assert_eq!(example, "# app\nA=\nB= # note\nBARE\n#\n");
Source§

impl Document<'_>

Source

pub fn format( &self, options: &FormatOptions, ) -> Result<FormatResult, FormatError>

Apply trivia-only formatting and verify that every declaration survives.

Invalid and ignored statements are not rewritten. Multiline value bodies are not modified; only final-line trivia, whole-line comments and blank lines are trimmed. The complete output is reparsed with this document’s exact dialect before it is returned.

§Errors

Returns FormatError::WouldChangeMeaning if the complete output does not preserve declaration keys, values, states, quotes, exports, lookup participation, inline comments, item kinds or malformed statement content.

§Examples
use adotenv::{parse_strict, EqualsSpacing, FormatOptions};

let doc = parse_strict("A=1\nB =  2\n").unwrap();
let formatted = doc
    .format(&FormatOptions {
        equals_spacing: EqualsSpacing::Spaces,
        ..FormatOptions::default()
    })
    .unwrap();
assert_eq!(formatted.as_str(), "A = 1\nB = 2\n");
Source§

impl Document<'_>

Source

pub fn source(&self) -> &str

The complete, unmodified input, including the BOM and malformed syntax.

Source

pub const fn dialect(&self) -> Dialect

The exact syntax and literal lookup policy used for this interpretation.

Source

pub fn reparse(&self, dialect: Dialect) -> (Document<'_>, Vec<Diagnostic>)

Interpret the retained text again, borrowing it without copying source bytes.

Source

pub fn items( &self, ) -> impl DoubleEndedIterator<Item = Item<'_>> + ExactSizeIterator

All source items in order; a leading BOM is the separate prelude.

Source

pub fn item(&self, index: usize) -> Option<Item<'_>>

One source item by its zero-based snapshot-local identity.

Source

pub fn entries( &self, ) -> impl DoubleEndedIterator<Item = Entry<'_>> + ExactSizeIterator

Valid declarations in source order, including duplicates and bare keys.

Source

pub fn entry(&self, index: usize) -> Option<Entry<'_>>

One declaration by its zero-based snapshot-local identity.

Source

pub fn get_all<'doc, 'key>( &'doc self, key: &'key str, ) -> impl DoubleEndedIterator<Item = Entry<'doc>> + 'key
where 'doc: 'key,

Every occurrence of a key in source order.

Source

pub fn get_entry(&self, key: &str) -> Option<Entry<'_>>

The winning participating declaration according to the dialect’s policy.

Source

pub fn get(&self, key: &str) -> Option<&str>

The effective literal lookup value, without environment inheritance.

BareKeys::Empty returns Some("") for a winning bare declaration, while that declaration’s Entry::value and syntax state remain bare.

Source

pub fn unique(&self, key: &str) -> Result<Entry<'_>, EditError>

Select a unique declaration without guessing between duplicate occurrences.

§Errors

Returns EditError::Missing or EditError::Duplicate.

Source

pub const fn has_bom(&self) -> bool

Whether one leading UTF-8 BOM is retained as a separate source prelude.

Source

pub fn bom_span(&self) -> Option<Range<usize>>

The BOM byte range, when present.

Source

pub fn has_final_newline(&self) -> bool

Whether the source ends in LF, CRLF or lone CR.

Source

pub fn line_index(&self) -> LineIndex<'_>

Build an explicit source index without imposing an index allocation on parsing.

Source

pub fn into_owned(self) -> Document<'static>

Retain all metadata and consume owned source, copying borrowed source only here.

Source§

impl Document<'_>

Source

pub fn portability(&self, dialects: &[Dialect]) -> PortabilityReport

Compare this document’s exact configuration and additional dialects.

The document’s own configuration is always the first reading; duplicate configurations are ignored. Each unique configuration parses the retained source once. A difference is reported for every physical line whose declarations, decoded values, assignment states, export prefixes, lookup participation, duplicate lookup winner or item grouping differ. Quote style alone is not a difference. No expansion, lookup, I/O or environment access occurs.

Differences are per physical line and ordered by line. A multiline item contributes a declaration on its first line and PortabilityPart::Continuation parts on its later lines, so grouping changes remain visible.

§Examples
use adotenv::{parse_with, Dialect};

let (doc, _) = parse_with("A=a#b\n", Dialect::PORTABLE);
let report = doc.portability(&[Dialect::NODE_DOTENV]);
assert_eq!(report.len(), 1);
let difference = &report.differences()[0];
assert_eq!(difference.first_line, 1);
assert_eq!(difference.readings.len(), 2);
Source§

impl Document<'_>

Source

pub fn resolve<F>( &self, lookup: F, options: &ExpandOptions, ) -> Result<ResolvedDocument, ResolveError>
where F: Fn(&str) -> Option<String>,

Resolve eligible variable references with an explicit caller lookup.

The lookup closure is consulted only when the selected order reaches it; no process environment, file or command access occurs. Command forms and ineligible references remain literal in this slice. Every substituted variable records its direct file or caller origin and, for file bindings, nested provenance.

§Errors

Returns a structured error for required variables, unresolved variables under Unresolved::Error, reachable cycles, or configured limits.

§Examples
use adotenv::{parse_strict, ExpandOptions};

let doc = parse_strict("A=base\nB=${A}-suffix\n").unwrap();
let resolved = doc
    .resolve(|_| None, &ExpandOptions::portable())
    .unwrap();
assert_eq!(resolved.entries()[1].value.as_deref(), Some("base-suffix"));
Source

pub fn resolve_with_commands<F, C>( &self, lookup: F, commands: C, source_identity: Option<&str>, options: &ExpandOptions, ) -> Result<ResolvedDocument, ResolveFailure>

Resolve with an explicit command-substitution callback.

Commands are invoked only when both ReferenceRules::commands and this callback permit them. The callback receives the raw command text, source spans and the supplied source identity. Outputs are literal resolved data. Every call is recorded; ResolveFailure::commands retains calls made before a later error. No shell, environment or file access is implied.

§Errors

Returns the same structured errors as Self::resolve, wraps callback failures, and retains prior command-call provenance in ResolveFailure.

Source§

impl Document<'_>

Source

pub fn deserialize<T: DeserializeOwned>(&self) -> Result<T, DeserializeError>

Deserialize effective literal declarations into a Serde type.

Duplicate keys follow the selected dialect; nonparticipating declarations and empty keys are ignored. Bare declarations are exposed only when the dialect’s BareKeys::Empty policy makes them effective empty strings. Values remain literal and are never expanded.

§Errors

Returns DeserializeError when a value cannot be parsed as the requested type. Value-conversion errors carry the declaration line.

§Examples
use adotenv::parse_strict;

#[derive(serde::Deserialize)]
struct Config {
    host: String,
    port: u16,
}

let doc = parse_strict("host=localhost\nport=8080\n").unwrap();
let config: Config = doc.deserialize().unwrap();
assert_eq!(config.host, "localhost");
assert_eq!(config.port, 8080);
Source§

impl Document<'_>

Source

pub fn sort(&self) -> Result<FormatResult, FormatError>

Sort declarations within each blank-line-separated group by key.

Comments before the first entry of a group stay at the top as a group header. Comments immediately before later entries move with those entries. Comments after the last entry stay at the bottom. Inline comments are part of the moved entry.

${VAR} dependencies between keys in the same group are respected: a referenced key is placed before the key that references it. Groups with empty/duplicate keys, malformed or ignored items, or dependency cycles are left byte-for-byte unchanged. Dependencies on keys outside the group are not ordering constraints.

The result is reparsed and verified before it is returned.

§Errors

Returns FormatError::WouldChangeMeaning if the generated text cannot be verified.

§Examples
use adotenv::parse_strict;

let doc = parse_strict("B=${A}\nA=1\n").unwrap();
let sorted = doc.sort().unwrap();
assert_eq!(sorted.as_str(), "A=1\nB=${A}\n");
Source§

impl Document<'_>

Source

pub fn groups(&self) -> Groups<'_> ⓘ

Blank-line-separated groups in source order.

Source

pub fn header(&self) -> Option<Group<'_>>

Items before the first declaration, when any exist.

This is a structural header view, not a separate syntax kind. It can contain comments and blank lines and excludes the BOM prelude.

Trait Implementations§

Source§

impl<'src> Clone for Document<'src>

Source§

fn clone(&self) -> Self

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<'src> Debug for Document<'src>

Source§

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

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

impl Display for Document<'_>

Source§

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

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

impl<'src> Eq for Document<'src>

Source§

impl<'src> PartialEq for Document<'src>

Source§

fn eq(&self, other: &Self) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl<'src> StructuralPartialEq for Document<'src>

Auto Trait Implementations§

§

impl<'src> Freeze for Document<'src>

§

impl<'src> RefUnwindSafe for Document<'src>

§

impl<'src> Send for Document<'src>

§

impl<'src> Sync for Document<'src>

§

impl<'src> Unpin for Document<'src>

§

impl<'src> UnsafeUnpin for Document<'src>

§

impl<'src> UnwindSafe for Document<'src>

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, 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<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> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

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.