m2_syn/lex/token_stream/
punct.rs1use std::sync::Arc;
2
3use crate::{Source, Span, Spanned};
4
5use super::{LeadingTrivia, Lex, Terminal, TokenStream, TokenTree, TrailingTrivia};
6
7#[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 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 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 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}