Skip to main content

links_notation/
parser_config.rs

1use crate::parser::DEFAULT_MAX_DEPTH;
2
3/// ParserConfig for reading Links Notation documents.
4///
5/// Provides configuration options for controlling how a document is read.
6#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct ParserConfig {
8    /// If true, a `#` written where a line or a token starts opens a comment
9    /// that runs to the end of the line (default: true)
10    pub comments: bool,
11    /// How deep links may nest: every parenthesized group and every indentation
12    /// level is one level. A document nested deeper is refused with
13    /// [`ParseError::NestingTooDeep`](crate::ParseError::NestingTooDeep) rather
14    /// than recursed into until the stack overflows
15    /// (default: [`DEFAULT_MAX_DEPTH`](crate::parser::DEFAULT_MAX_DEPTH))
16    pub max_depth: usize,
17}
18
19impl Default for ParserConfig {
20    fn default() -> Self {
21        Self {
22            comments: true,
23            max_depth: DEFAULT_MAX_DEPTH,
24        }
25    }
26}
27
28impl ParserConfig {
29    /// Create a new ParserConfig with default values
30    ///
31    /// # Examples
32    /// ```
33    /// use links_notation::ParserConfig;
34    ///
35    /// assert!(ParserConfig::new().comments);
36    /// ```
37    pub fn new() -> Self {
38        Self::default()
39    }
40
41    /// Create a ParserConfig that reads `#` as an ordinary reference character,
42    /// the way documents written before comments existed were read.
43    ///
44    /// # Examples
45    /// ```
46    /// use links_notation::{parse_lino_with_config, ParserConfig};
47    ///
48    /// let parsed = parse_lino_with_config("# a b", &ParserConfig::without_comments()).unwrap();
49    /// assert_eq!(format!("{}", parsed), "((# a b))");
50    /// ```
51    pub fn without_comments() -> Self {
52        Self::with_comments(false)
53    }
54
55    /// Create a ParserConfig that turns comments on or off
56    ///
57    /// # Examples
58    /// ```
59    /// use links_notation::ParserConfig;
60    ///
61    /// assert_eq!(ParserConfig::with_comments(false), ParserConfig::without_comments());
62    /// ```
63    pub fn with_comments(comments: bool) -> Self {
64        Self {
65            comments,
66            ..Self::default()
67        }
68    }
69
70    /// The same configuration, refusing links nested deeper than `max_depth`.
71    ///
72    /// Every level of nesting is a level of recursion in the parser, so raising
73    /// the limit far past the default is only safe on a larger stack.
74    ///
75    /// # Examples
76    /// ```
77    /// use links_notation::{parse_lino_to_links_with_config, ParseError, ParserConfig};
78    ///
79    /// let config = ParserConfig::new().with_max_depth(2);
80    /// assert!(parse_lino_to_links_with_config("((a))", &config).is_ok());
81    /// assert!(matches!(
82    ///     parse_lino_to_links_with_config("(((a)))", &config),
83    ///     Err(ParseError::NestingTooDeep(_))
84    /// ));
85    /// ```
86    pub fn with_max_depth(mut self, max_depth: usize) -> Self {
87        self.max_depth = max_depth;
88        self
89    }
90}