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,
12 leading_trivia: LeadingTrivia,
14 trailing_trivia: TrailingTrivia,
16}
17
18impl Punct {
19 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 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 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}