Skip to main content

m2_syn/lex/token_stream/
punct.rs

1use std::fmt::{Display, Formatter, Result};
2use std::sync::Arc;
3
4use crate::{Span, Spanned};
5
6use super::{Lex, TokenStream, TokenTree};
7
8/// One maximal-munch M2 punctuation token.
9#[derive(Debug, Clone, PartialEq, Eq, Hash, Spanned)]
10pub struct Punct {
11    span: Span,
12}
13
14impl Punct {
15    /// Creates punctuation whose spelling is already available through its span.
16    ///
17    /// # Panics
18    ///
19    /// Panics when `span` has no source backing.
20    pub fn from_span(span: Span) -> Self {
21        assert!(
22            span.text().is_some(),
23            "punctuation spans must name source text"
24        );
25        Self { span }
26    }
27
28    /// Creates punctuation with its source spelling and span.
29    pub fn new(text: impl Into<Arc<str>>, span: Span) -> Self {
30        Self {
31            span: span.with_text(text),
32        }
33    }
34
35    /// Returns the punctuation spelling.
36    ///
37    /// # Panics
38    ///
39    /// Panics if this token's invariant that its span is source-backed was violated.
40    pub fn text(&self) -> &str {
41        self.span
42            .text()
43            .expect("punctuation tokens must have source-backed spans")
44    }
45}
46
47impl Display for Punct {
48    fn fmt(&self, formatter: &mut Formatter<'_>) -> Result {
49        formatter.write_str(self.text())
50    }
51}
52
53impl Lex for Punct {
54    fn to_tokens(&self, output: &mut TokenStream) {
55        output.0.push(TokenTree::Punct(self.clone()));
56    }
57}