1use crate::lex::{Cursor, LexError, Scan};
2use crate::span::DelimSpan;
3use crate::{Delim, Span, TokenStream, TokenTree};
4
5#[derive(Debug, Clone, PartialEq, Eq)]
7pub struct Group {
8 pub delim: Delim,
9 pub span: DelimSpan,
10 pub tokens: TokenStream,
11}
12
13impl Group {
14 #[inline]
15 pub fn new(delim: Delim, stream: TokenStream) -> Self {
16 Self {
17 delim,
18 span: DelimSpan::new(Span::call_site(), Span::call_site()),
19 tokens: stream,
20 }
21 }
22
23 #[inline]
24 pub fn to_token_tree(&self) -> TokenTree {
25 TokenTree::Group(self.clone())
26 }
27
28 #[inline]
29 pub fn into_token_tree(self) -> TokenTree {
30 TokenTree::Group(self)
31 }
32}
33
34impl std::fmt::Display for Group {
35 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36 match self.delim {
37 Delim::None => write!(f, "{}", self.tokens),
38 d => write!(f, "{}{}{}", d.open(), self.tokens, d.close()),
39 }
40 }
41}
42
43impl Scan for Group {
44 fn scan(cursor: Cursor<'_>) -> Result<(Cursor<'_>, Self), LexError> {
45 let ch = cursor.first().ok_or(cursor.error())?;
46 let delim = Delim::from_open(ch).ok_or(cursor.error())?;
47 let c = cursor.advance_by(ch.len_utf8());
48 let (c, inner) = TokenStream::scan(c)?;
49 let close_ch = c
50 .first()
51 .ok_or_else(|| cursor.error().message(format!("unclosed delimiter '{}'", delim.open())))?;
52
53 let close_delim = Delim::from_close(close_ch).ok_or_else(|| {
54 c.error()
55 .message(format!("expected '{}', found '{}'", delim.close(), close_ch))
56 })?;
57
58 if delim != close_delim {
59 return Err(c.error().message(format!(
60 "mismatched delimiter: expected '{}', found '{}'",
61 delim.close(),
62 close_ch,
63 )));
64 }
65
66 let c = c.advance_by(close_ch.len_utf8());
67 let mut group = Self::new(delim, inner);
68 group.span = DelimSpan::new(cursor.span(), c.span());
69
70 Ok((c, group))
71 }
72}
73
74impl crate::ToTokens for Group {
75 fn to_tokens(&self, tokens: &mut crate::TokenStream) {
76 tokens.extend_one(crate::TokenTree::Group(self.clone()));
77 }
78}
79
80impl crate::Spanner for Group {
81 fn span(&self) -> Span {
82 self.span.span()
83 }
84}
85
86#[cfg(feature = "serde")]
87impl serde::Serialize for Group {
88 fn serialize<S>(&self, s: S) -> Result<S::Ok, S::Error>
89 where
90 S: serde::Serializer,
91 {
92 use serde::ser::SerializeStruct;
93
94 let mut o = s.serialize_struct("Group", 2)?;
95 o.serialize_field("delim", &self.delim)?;
96 o.serialize_field("tokens", &self.tokens)?;
97 o.end()
98 }
99}