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    span: Span,
11    leading_trivia: LeadingTrivia,
12    trailing_trivia: TrailingTrivia,
13}
14
15impl Punct {
16    /// Creates punctuation from its source span.
17    pub fn from_span(span: Span) -> Self {
18        Self {
19            span,
20            leading_trivia: LeadingTrivia::default(),
21            trailing_trivia: TrailingTrivia::default(),
22        }
23    }
24
25    /// Creates punctuation with its source spelling and span.
26    pub fn new(text: impl Into<Arc<str>>, span: Span) -> Self {
27        let text = text.into();
28        let span = if span.text() == Some(text.as_ref()) {
29            span
30        } else {
31            let source = Source::with_file(span.file(), text);
32            let len = source.text().len();
33            Span::ranged(source, 0..len)
34        };
35        Self {
36            span,
37            leading_trivia: LeadingTrivia::default(),
38            trailing_trivia: TrailingTrivia::default(),
39        }
40    }
41
42    /// Returns the punctuation spelling.
43    ///
44    /// # Panics
45    ///
46    /// Panics when `sources` cannot resolve this token's span.
47    pub fn text(&self) -> &str {
48        self.span
49            .text()
50            .expect("punctuation spans must resolve to source text")
51    }
52}
53
54impl Lex for Punct {
55    fn to_tokens(&self, output: &mut TokenStream) {
56        output.push(TokenTree::Punct(self.clone()));
57    }
58}
59
60impl Terminal for Punct {
61    fn leading_trivia(&self) -> &LeadingTrivia {
62        &self.leading_trivia
63    }
64
65    fn leading_trivia_mut(&mut self) -> &mut LeadingTrivia {
66        &mut self.leading_trivia
67    }
68
69    fn trailing_trivia(&self) -> &TrailingTrivia {
70        &self.trailing_trivia
71    }
72
73    fn trailing_trivia_mut(&mut self) -> &mut TrailingTrivia {
74        &mut self.trailing_trivia
75    }
76}