Skip to main content

lex_core/lex/ast/elements/
parameter.rs

1//! Parameter element
2//!
3//!     A parameter is a pair of key and value. Parameters are components that carry a bit
4//!     of information inside an element, only used in metadata. They can be used in
5//!     annotations and verbatim blocks to convey structured metadata.
6//!
7//!     Together with labels, parameters allow for structured metadata. They are used in
8//!     data nodes, which have the syntax:
9//!         :: label params?
10//!
11//! Syntax
12//!
13//!     <key> "=" <value>
14//!
15//!     Examples:
16//!         priority=high
17//!         severity=high
18//!
19//!     Parameters are optional in data nodes. Multiple parameters can be specified
20//!     separated by whitespace.
21//!
22//!     See [Data](super::data::Data) for how parameters are used in data nodes.
23//!
24//!     Learn More:
25//!         - Parameters spec: specs/v1/elements/parameter.lex
26
27use super::super::range::{Position, Range};
28use crate::lex::escape::unescape_quoted;
29use std::fmt;
30
31/// A parameter represents a key-value pair
32#[derive(Debug, Clone, PartialEq)]
33pub struct Parameter {
34    pub key: String,
35    pub value: String,
36    pub location: Range,
37}
38
39impl Parameter {
40    fn default_location() -> Range {
41        Range::new(0..0, Position::new(0, 0), Position::new(0, 0))
42    }
43
44    pub fn new(key: String, value: String) -> Self {
45        Self {
46            key,
47            value,
48            location: Self::default_location(),
49        }
50    }
51
52    /// Preferred builder
53    pub fn at(mut self, location: Range) -> Self {
54        self.location = location;
55        self
56    }
57
58    /// Returns the semantic value with outer quotes stripped and escapes resolved.
59    ///
60    /// For quoted values like `"Hello World"`, returns `Hello World`.
61    /// For values with escapes like `"say \"hello\""`, returns `say "hello"`.
62    /// For unquoted values like `simple`, returns `simple` unchanged.
63    pub fn unquoted_value(&self) -> String {
64        unescape_quoted(&self.value)
65    }
66}
67
68impl fmt::Display for Parameter {
69    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
70        write!(f, "{}={}", self.key, self.value)
71    }
72}
73
74#[cfg(test)]
75mod tests {
76    use super::*;
77
78    #[test]
79    fn test_parameter() {
80        let location = super::super::super::range::Range::new(
81            0..0,
82            super::super::super::range::Position::new(1, 0),
83            super::super::super::range::Position::new(1, 10),
84        );
85        let param = Parameter::new("key".to_string(), "value".to_string()).at(location.clone());
86        assert_eq!(param.location, location);
87    }
88}