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}