Skip to main content

arity_parser/
dcf.rs

1//! A lossless CST parser for DCF (Debian Control Format) — R's `DESCRIPTION`
2//! format.
3//!
4//! This is a **second grammar** in this crate, independent of the R one. It
5//! exists because `DESCRIPTION` is not just a bag of facts to scrape: it wants
6//! spans (for diagnostics), record structure, and byte-for-byte round-tripping
7//! (for formatting).
8//!
9//! - [`syntax`] — `SyntaxKind`, `DcfLanguage`, and the node/token aliases.
10//! - [`parser`] — `parse`, `reconstruct`, and `ParseOutput`.
11//! - [`ast`] — typed wrappers; **the** way to read a document from outside
12//!   this module, so no consumer ever has to name the second `SyntaxKind`.
13//!
14//! Losslessness holds exactly as it does for the R grammar:
15//! `reconstruct(text) == text`, byte for byte. Errors never abort the parse —
16//! diagnostics ride a side channel and every byte stays in the tree.
17//!
18//! ```
19//! use arity_parser::dcf;
20//!
21//! let output = dcf::parse("Package: mypkg\nDepends: R (>= 4.1.0)\n");
22//! let value = output.document().field("Depends").unwrap().folded_value();
23//! assert_eq!(value, "R (>= 4.1.0)");
24//! ```
25//!
26//! Two `SyntaxKind` enums now exist in this crate. They are distinct types
27//! sharing a name, disambiguated by module path — never glob-import both.
28
29pub mod ast;
30pub mod deps;
31pub mod parser;
32pub mod syntax;
33
34pub use ast::{CommentLine, Document, Field, MalformedLine, Record, ValueLine};
35pub use deps::{
36    DEPENDENCY_FIELDS, DependencyEntry, VersionConstraint, VersionOp, dependency_entries,
37    is_dependency_field,
38};
39pub use parser::{ParseOutput, parse, reconstruct};
40pub use syntax::{DcfLanguage, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken};
41
42pub use crate::parser::ParseDiagnostic;