rowan_peg_utils/
lib.rs

1use std::{cell::{Cell, RefCell}, mem::{forget, take}};
2
3use rowan::{GreenNode, GreenNodeBuilder, SyntaxKind};
4
5#[derive(Debug)]
6pub struct QuietGuard<'b, 'a>(&'b ParseState<'a>);
7
8impl<'b, 'a> std::ops::Deref for QuietGuard<'b, 'a> {
9    type Target = &'b ParseState<'a>;
10
11    fn deref(&self) -> &Self::Target {
12        &self.0
13    }
14}
15
16impl<'b, 'a> Drop for QuietGuard<'b, 'a> {
17    fn drop(&mut self) {
18        self.0.quiet.update(|n| n+1);
19    }
20}
21
22#[derive(Debug)]
23pub struct RuleGuard<'b, 'a> {
24    state: &'b ParseState<'a>,
25    len: usize,
26    quiet: u32,
27    kind: SyntaxKind,
28}
29
30impl<'b, 'a> RuleGuard<'b, 'a> {
31    fn end_set(&self) {
32        self.state.quiet.set(self.quiet);
33    }
34
35    pub fn accept_token(self, text: &'a str) {
36        self.end_set();
37        self.state.action(Action::Token(self.kind, text));
38        forget(self);
39    }
40
41    pub fn accept_none(self) {
42        self.end_set();
43        forget(self);
44    }
45
46    pub fn accept(self) {
47        self.end_set();
48        self.state.action(Action::Finish);
49        forget(self);
50    }
51}
52
53impl<'b, 'a> Drop for RuleGuard<'b, 'a> {
54    fn drop(&mut self) {
55        let RuleGuard { state, len, quiet, kind: _ } = *self;
56        state.actions.borrow_mut().truncate(len);
57        state.quiet.set(quiet);
58    }
59}
60
61#[derive(Debug, Clone)]
62pub enum Action<'a> {
63    Token(SyntaxKind, &'a str),
64    Start(SyntaxKind),
65    Finish,
66}
67
68#[derive(Debug, Default)]
69pub struct ParseState<'a> {
70    actions: RefCell<Vec<Action<'a>>>,
71    quiet: Cell<u32>,
72    builder: GreenNodeBuilder<'static>,
73}
74
75impl<'a> ParseState<'a> {
76    pub fn clear(&mut self) {
77        let mut actions = take(&mut self.actions);
78        actions.get_mut().clear();
79        *self = Self {
80            actions,
81            quiet: 0.into(),
82            ..Default::default()
83        }
84    }
85
86    pub fn action(&self, action: Action<'a>) {
87        if self.quiet.get() == 0 {
88            self.actions.borrow_mut().push(action);
89        }
90    }
91
92    pub fn quiet(&self) -> QuietGuard<'_, 'a> {
93        QuietGuard(self)
94    }
95
96    pub fn guard(&self, kind: impl Into<SyntaxKind>) -> RuleGuard<'_, 'a> {
97        let kind = kind.into();
98        let guard = self.guard_token(kind);
99        self.action(Action::Start(kind.into()));
100        guard
101    }
102
103    pub fn guard_token(&self, kind: impl Into<SyntaxKind>) -> RuleGuard<'_, 'a> {
104        let len = self.actions.borrow().len();
105        RuleGuard { state: self, len, quiet: self.quiet.get(), kind: kind.into() }
106    }
107
108    pub fn guard_none(&self) -> RuleGuard<'_, 'a> {
109        let kind = SyntaxKind(0);
110        self.guard_token(kind)
111    }
112
113    pub fn finish(&mut self) -> GreenNode {
114        for action in self.actions.get_mut().drain(..) {
115            match action {
116                Action::Token(kind, text) => {
117                    if !text.is_empty() {
118                        self.builder.token(kind, text)
119                    }
120                }
121                Action::Start(kind) => self.builder.start_node(kind),
122                Action::Finish => self.builder.finish_node(),
123            }
124        }
125        take(&mut self.builder).finish()
126    }
127}