1use std::fmt::{Display, Formatter};
8use std::ops::Bound;
9
10use crate::{
11 Lex, Parse, ParseStream, Span, Spanned, TokenGroup, TokenParseError, TokenStream, TokenTree,
12 TrailingTrivia,
13};
14
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16pub enum DelimiterKind {
23 Parenthesis,
25 Bracket,
27 Brace,
29 AngleBar,
31}
32
33impl DelimiterKind {
34 pub const fn expression_name(self) -> &'static str {
36 match self {
37 Self::Parenthesis => "parenthesized expression",
38 Self::Bracket => "array expression",
39 Self::Brace => "list expression",
40 Self::AngleBar => "angle-bar list expression",
41 }
42 }
43}
44
45pub trait DelimiterValue: Spanned + Lex + Sized {
50 fn from_delimiter(delimiter: Delimiter) -> Option<Self>;
52
53 fn delimiter(&self) -> Delimiter;
55
56 fn expected() -> &'static str;
58
59 fn opening_trivia(&self) -> &TrailingTrivia;
61
62 fn opening_trivia_mut(&mut self) -> &mut TrailingTrivia;
64
65 fn closing_trivia(&self) -> &TrailingTrivia;
67
68 fn closing_trivia_mut(&mut self) -> &mut TrailingTrivia;
70
71 fn surround(&self, output: &mut TokenStream, contents: TokenStream) {
73 let mut grouped = TokenStream::new();
74 self.opening_trivia().to_tokens(&mut grouped);
75 contents.to_tokens(&mut grouped);
76 output.extend([TokenGroup::new(self.delimiter(), grouped)]);
77 self.closing_trivia().to_tokens(output);
78 }
79}
80
81pub trait DelimiterToken: Parse + DelimiterValue {
87 const KIND: DelimiterKind;
89
90 fn new(spans: DoubleSpan) -> Self;
92
93 fn spans(&self) -> DoubleSpan;
96}
97
98#[derive(Debug, Clone, PartialEq, Eq)]
107pub struct DoubleSpan(pub Span, pub Bound<Span>);
108
109impl DoubleSpan {
110 pub fn new(open: Span, close: Span) -> Self {
112 Self(open, Bound::Included(close))
113 }
114
115 pub fn synthetic(kind: DelimiterKind) -> Self {
117 let spelling = format!("{}{}", kind.opening(), kind.closing());
118 let span = Span::for_text(spelling);
119 let boundary = kind.opening().len();
120 Self::new(
121 span.subspan(0, boundary),
122 span.subspan(boundary, span.len().unwrap_or(boundary)),
123 )
124 }
125
126 pub fn unclosed(open: Span) -> Self {
128 Self(open, Bound::Unbounded)
129 }
130
131 pub fn open(&self) -> Span {
133 self.0.clone()
134 }
135
136 pub fn close(&self) -> Option<Span> {
138 match &self.1 {
139 Bound::Included(span) | Bound::Excluded(span) => Some(span.clone()),
140 Bound::Unbounded => None,
141 }
142 }
143
144 pub fn close_bound(&self) -> Bound<Span> {
147 self.1.clone()
148 }
149
150 pub(crate) fn complete(&mut self, close: Span) {
152 debug_assert!(matches!(self.1, Bound::Unbounded));
153 self.1 = Bound::Included(close);
154 }
155
156 pub fn is_closed(&self) -> bool {
158 !matches!(self.1, Bound::Unbounded)
159 }
160}
161
162impl Spanned for DoubleSpan {
163 fn try_span(&self) -> Option<Span> {
164 self.close()
165 .and_then(|close| self.0.join(close))
166 .or_else(|| Some(self.0.clone()))
167 }
168}
169
170#[derive(Debug, Clone, PartialEq, Eq)]
171pub struct Delimiter {
173 pub kind: DelimiterKind,
175 pub spans: DoubleSpan,
177 opening_trivia: TrailingTrivia,
178 closing_trivia: TrailingTrivia,
179}
180
181impl Delimiter {
182 pub fn new(kind: DelimiterKind, spans: DoubleSpan) -> Self {
184 Self {
185 kind,
186 spans,
187 opening_trivia: TrailingTrivia::default(),
188 closing_trivia: TrailingTrivia::default(),
189 }
190 }
191
192 pub fn opening_span(&self) -> Span {
194 self.spans.open()
195 }
196
197 pub fn closing_span(&self) -> Option<Span> {
199 self.spans.close()
200 }
201
202 pub fn is_closed(&self) -> bool {
204 self.spans.is_closed()
205 }
206}
207
208impl Spanned for Delimiter {
209 fn try_span(&self) -> Option<Span> {
210 self.spans.try_span()
211 }
212}
213
214impl DelimiterValue for Delimiter {
215 fn from_delimiter(delimiter: Delimiter) -> Option<Self> {
216 Some(delimiter)
217 }
218
219 fn delimiter(&self) -> Delimiter {
220 self.clone()
221 }
222
223 fn expected() -> &'static str {
224 "a delimited group"
225 }
226
227 fn opening_trivia(&self) -> &TrailingTrivia {
228 &self.opening_trivia
229 }
230
231 fn opening_trivia_mut(&mut self) -> &mut TrailingTrivia {
232 &mut self.opening_trivia
233 }
234
235 fn closing_trivia(&self) -> &TrailingTrivia {
236 &self.closing_trivia
237 }
238
239 fn closing_trivia_mut(&mut self) -> &mut TrailingTrivia {
240 &mut self.closing_trivia
241 }
242}
243
244impl Parse for Delimiter {
245 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
246 let group = parse_any_group(input, Self::expected())?;
247 if !group.stream().is_empty() {
248 return Err(TokenParseError::unexpected(
249 "an empty delimited group",
250 group.delim_kind().opening(),
251 group.expect_span(),
252 ));
253 }
254 Ok(group.delimiter().clone())
255 }
256}
257
258impl Lex for Delimiter {
259 fn to_tokens(&self, output: &mut TokenStream) {
260 self.surround(output, TokenStream::new());
261 }
262}
263
264#[doc(hidden)]
266pub fn parse_delimiter<D: DelimiterToken>(input: &mut ParseStream) -> Result<D, TokenParseError> {
267 let kind = D::KIND;
268 let group = parse_group(input, kind)?;
269 if !group.stream().is_empty() {
270 return Err(TokenParseError::unexpected(
271 kind.opening(),
272 kind.opening(),
273 group.expect_span(),
274 ));
275 }
276 Ok(D::new(group.delimiter().spans.clone()))
277}
278
279pub(crate) fn parse_group(
280 input: &mut ParseStream,
281 kind: DelimiterKind,
282) -> Result<TokenGroup, TokenParseError> {
283 let group = parse_any_group(input, kind.opening())?;
284 if group.delim_kind() != kind {
285 return Err(TokenParseError::unexpected(
286 kind.opening(),
287 group.delim_kind().opening(),
288 group.expect_span(),
289 ));
290 }
291 Ok(group)
292}
293
294pub(crate) fn parse_any_group(
295 input: &mut ParseStream,
296 expected: &'static str,
297) -> Result<TokenGroup, TokenParseError> {
298 let Some(token) = input.next_token() else {
299 return Err(TokenParseError::unexpected_end(expected, input.eof_span()));
300 };
301 let TokenTree::Group(group) = token else {
302 return Err(TokenParseError::unexpected_token(expected, &token));
303 };
304 Ok(group)
305}
306
307impl Display for Delimiter {
308 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
309 formatter.write_str(self.kind.opening())
310 }
311}
312impl Display for DelimiterKind {
313 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
314 formatter.write_str(self.opening())
315 }
316}
317
318impl DelimiterKind {
319 pub fn opening(self) -> &'static str {
321 match self {
322 Self::Parenthesis => "(",
323 Self::Bracket => "[",
324 Self::Brace => "{",
325 Self::AngleBar => "<|",
326 }
327 }
328
329 pub fn closing(self) -> &'static str {
331 match self {
332 Self::Parenthesis => ")",
333 Self::Bracket => "]",
334 Self::Brace => "}",
335 Self::AngleBar => "|>",
336 }
337 }
338}