Skip to main content

lex_core/lex/ast/elements/
data.rs

1//! Data Node
2//!
3//!     Data nodes encapsulate the reusable :: label parameters? header shared by
4//!     annotations and future elements. They carry the label plus optional parameters
5//!     but no closing :: marker or content.
6//!
7//!     In keeping with Lex's ethos of putting content first there is only one formal
8//!     syntax element: the lex-marker, a double colon (::). Accordingly, it's only used
9//!     in metadata, there is in Data nodes. Data nodes group a label (an identifier) and
10//!     optional parameters.
11//!
12//! Syntax
13//!
14//!     <data> = <lex-marker> <whitespace> <label> (<whitespace> <parameters>)?
15//!
16//!     Examples:
17//!         :: note
18//!         :: note severity=high
19//!         :: syntax
20//!
21//!     Data nodes always appear at the start of a line (after whitespace), so they are
22//!     very easy to identify.
23//!
24//!     The lex-marker (::) is the only formal syntax element introduced by Lex. All other
25//!     markers are naturally occurring in ordinary text, and with the meaning they already
26//!     convey.
27//!
28//!     See [Label](super::label::Label) and [Parameter](super::parameter::Parameter) for
29//!     the component elements that make up data nodes.
30
31use super::super::range::{Position, Range};
32use super::label::Label;
33use super::parameter::Parameter;
34use std::fmt;
35
36/// Structured data payload extracted from `:: label params?` headers.
37#[derive(Debug, Clone, PartialEq)]
38pub struct Data {
39    pub label: Label,
40    pub parameters: Vec<Parameter>,
41    pub location: Range,
42}
43
44impl Data {
45    fn default_location() -> Range {
46        Range::new(0..0, Position::new(0, 0), Position::new(0, 0))
47    }
48
49    pub fn new(label: Label, parameters: Vec<Parameter>) -> Self {
50        Self {
51            label,
52            parameters,
53            location: Self::default_location(),
54        }
55    }
56
57    pub fn at(mut self, location: Range) -> Self {
58        self.location = location;
59        self
60    }
61}
62
63impl fmt::Display for Data {
64    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
65        write!(
66            f,
67            "Data('{}', {} params)",
68            self.label.value,
69            self.parameters.len()
70        )
71    }
72}