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}