Skip to main content

m2_syn/lex/token_stream/
punct.rs

1use std::sync::Arc;
2
3use crate::{Source, Span, Spanned};
4
5use super::{LeadingTrivia, Lex, Terminal, TokenStream, TokenTree, TrailingTrivia};
6
7/// One maximal-munch M2 punctuation token.
8#[derive(Debug, Clone, PartialEq, Eq, Hash, Spanned)]
9pub struct Punct {
10    /// The span.
11    span: Span,
12    /// The leading trivia.
13    leading_trivia: LeadingTrivia,
14    /// The trailing trivia.
15    trailing_trivia: TrailingTrivia,
16}
17
18impl Punct {
19    /// Creates punctuation from its source span.
20    pub fn from_span(span: Span) -> Self {
21        Self {
22            span,
23            leading_trivia: LeadingTrivia::default(),
24            trailing_trivia: TrailingTrivia::default(),
25        }
26    }
27
28    /// Creates punctuation with its source spelling and span.
29    pub fn new(text: impl Into<Arc<str>>, span: Span) -> Self {
30        let text = text.into();
31        let span = if span.text() == Some(text.as_ref()) {
32            span
33        } else {
34            let source = Source::with_file(span.file(), text);
35            let len = source.text().len();
36            Span::ranged(source, 0..len)
37        };
38        Self {
39            span,
40            leading_trivia: LeadingTrivia::default(),
41            trailing_trivia: TrailingTrivia::default(),
42        }
43    }
44
45    /// Returns the punctuation spelling.
46    ///
47    /// # Panics
48    ///
49    /// Panics when `sources` cannot resolve this token's span.
50    pub fn text(&self) -> &str {
51        self.span
52            .text()
53            .expect("punctuation spans must resolve to source text")
54    }
55}
56
57impl Lex for Punct {
58    fn to_tokens(&self, output: &mut TokenStream) {
59        output.push(TokenTree::Punct(self.clone()));
60    }
61}
62
63impl Terminal for Punct {
64    fn leading_trivia(&self) -> &LeadingTrivia {
65        &self.leading_trivia
66    }
67
68    fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia {
69        &mut self.leading_trivia
70    }
71
72    fn trailing_trivia(&self) -> &TrailingTrivia {
73        &self.trailing_trivia
74    }
75
76    fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia {
77        &mut self.trailing_trivia
78    }
79}