Skip to main content

svugy_parse/d2/
mod.rs

1//! Import a d2 v0.9.0 file into the model through svugy's v1 d2 subset and its `vars: { svugy: { … } }` carrier, reporting every syntax error and ignored construct.
2
3mod ast;
4mod carrier;
5mod diagnostic;
6mod lex;
7mod lower;
8mod parse;
9mod subset;
10
11/// Pin the d2 release (d2lang/d2, formerly terrastruct/d2; latest stable on 2026-11-06) whose grammar, keywords and compiler this importer and its golden files follow.
12pub const GRAMMAR_VERSION: &str = "v0.9.0";
13
14pub use ast::{
15    D2Document, EdgeDeclaration, EdgeLink, EdgeOperator, Field, FieldAssignment, KeyPath,
16    KeySegment, Scalar, ShapeDeclaration, Span, Statement, StyleProperty, SvugyProperty,
17};
18pub use diagnostic::{Construct, D2Language, SyntaxError, UnsupportedConstruct};
19
20use crate::diagnostic::{Import, ImportParts};
21use diagnostic::Diagnostics;
22use lex::Token;
23use parse::SyntaxStatement;
24use subset::SubsetFilter;
25
26/// Collect what importing a d2 file yields: the model's admission, every syntax error, every construct the model does not hold.
27pub type D2Import = Import<D2Language>;
28
29/// Split a d2 import into its model, withheld while any diagnostic is an error, its syntax errors, its ignored constructs and the model's report.
30pub type D2ImportParts = ImportParts<D2Language>;
31
32/// Collect what parsing a d2 file yields: its partial document, every syntax error and every ignored construct.
33#[derive(Debug, Clone, PartialEq)]
34pub struct D2Parse {
35    pub document: D2Document,
36    pub errors: Vec<SyntaxError>,
37    pub warnings: Vec<UnsupportedConstruct>,
38}
39
40impl D2Parse {
41    /// Lex, parse and filter `source` to the v1 subset; broken statements are dropped and reported, never fatal.
42    pub fn parse(source: &str) -> Self {
43        let mut diagnostics = Diagnostics::default();
44        let tokens = Token::lex_all(source, &mut diagnostics);
45        let syntax_statements = SyntaxStatement::parse_all(&tokens, source, &mut diagnostics);
46        let document = SubsetFilter::filter_document(syntax_statements, &mut diagnostics);
47        let (errors, warnings) = diagnostics.into_sorted_parts();
48        Self {
49            document,
50            errors,
51            warnings,
52        }
53    }
54}