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};
14use these_macros_should_be_illegal::discriminated_str;
15#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
16#[discriminated_str(expression_name)]
23pub enum DelimiterKind {
24 Parenthesis = "parenthesized expression",
26 Bracket = "array expression",
28 Brace = "list expression",
30 AngleBar = "angle-bar list expression",
32}
33
34pub trait DelimiterValue: Spanned + Lex + Sized {
39 fn from_delimiter(delimiter: Delimiter) -> Option<Self>;
41
42 fn delimiter(&self) -> Delimiter;
44
45 fn expected() -> &'static str;
47
48 fn opening_trivia(&self) -> &TrailingTrivia;
50
51 fn opening_trivia_mut(&mut self) -> &mut TrailingTrivia;
53
54 fn closing_trivia(&self) -> &TrailingTrivia;
56
57 fn closing_trivia_mut(&mut self) -> &mut TrailingTrivia;
59
60 fn surround(&self, output: &mut TokenStream, contents: TokenStream) {
62 let mut grouped = TokenStream::new();
63 self.opening_trivia().to_tokens(&mut grouped);
64 contents.to_tokens(&mut grouped);
65 output.extend([TokenGroup::new(self.delimiter(), grouped)]);
66 self.closing_trivia().to_tokens(output);
67 }
68}
69
70pub trait DelimiterToken: Parse + DelimiterValue {
76 const KIND: DelimiterKind;
78
79 fn new(spans: DoubleSpan) -> Self;
81
82 fn spans(&self) -> DoubleSpan;
85}
86
87#[derive(Debug, Clone, PartialEq, Eq)]
96pub struct DoubleSpan(pub Span, pub Bound<Span>);
97
98impl DoubleSpan {
99 pub fn new(open: Span, close: Span) -> Self {
101 Self(open, Bound::Included(close))
102 }
103
104 pub fn synthetic(kind: DelimiterKind) -> Self {
106 let spelling = format!("{}{}", kind.opening(), kind.closing());
107 let span = Span::for_text(spelling);
108 let boundary = kind.opening().len();
109 Self::new(
110 span.subspan(0, boundary),
111 span.subspan(boundary, span.len().unwrap_or(boundary)),
112 )
113 }
114
115 pub fn unclosed(open: Span) -> Self {
117 Self(open, Bound::Unbounded)
118 }
119
120 pub fn open(&self) -> Span {
122 self.0.clone()
123 }
124
125 pub fn close(&self) -> Option<Span> {
127 match &self.1 {
128 Bound::Included(span) | Bound::Excluded(span) => Some(span.clone()),
129 Bound::Unbounded => None,
130 }
131 }
132
133 pub fn close_bound(&self) -> Bound<Span> {
136 self.1.clone()
137 }
138
139 pub(crate) fn complete(&mut self, close: Span) {
141 debug_assert!(matches!(self.1, Bound::Unbounded));
142 self.1 = Bound::Included(close);
143 }
144
145 pub fn is_closed(&self) -> bool {
147 !matches!(self.1, Bound::Unbounded)
148 }
149}
150
151impl Spanned for DoubleSpan {
152 fn try_span(&self) -> Option<Span> {
153 self.close()
154 .and_then(|close| self.0.join(close))
155 .or_else(|| Some(self.0.clone()))
156 }
157}
158
159#[derive(Debug, Clone, PartialEq, Eq)]
160pub struct Delimiter {
162 pub kind: DelimiterKind,
164 pub spans: DoubleSpan,
166 opening_trivia: TrailingTrivia,
167 closing_trivia: TrailingTrivia,
168}
169
170impl Delimiter {
171 pub fn new(kind: DelimiterKind, spans: DoubleSpan) -> Self {
173 Self {
174 kind,
175 spans,
176 opening_trivia: TrailingTrivia::default(),
177 closing_trivia: TrailingTrivia::default(),
178 }
179 }
180
181 pub fn opening_span(&self) -> Span {
183 self.spans.open()
184 }
185
186 pub fn closing_span(&self) -> Option<Span> {
188 self.spans.close()
189 }
190
191 pub fn is_closed(&self) -> bool {
193 self.spans.is_closed()
194 }
195}
196
197impl Spanned for Delimiter {
198 fn try_span(&self) -> Option<Span> {
199 self.spans.try_span()
200 }
201}
202
203impl DelimiterValue for Delimiter {
204 fn from_delimiter(delimiter: Delimiter) -> Option<Self> {
205 Some(delimiter)
206 }
207
208 fn delimiter(&self) -> Delimiter {
209 self.clone()
210 }
211
212 fn expected() -> &'static str {
213 "a delimited group"
214 }
215
216 fn opening_trivia(&self) -> &TrailingTrivia {
217 &self.opening_trivia
218 }
219
220 fn opening_trivia_mut(&mut self) -> &mut TrailingTrivia {
221 &mut self.opening_trivia
222 }
223
224 fn closing_trivia(&self) -> &TrailingTrivia {
225 &self.closing_trivia
226 }
227
228 fn closing_trivia_mut(&mut self) -> &mut TrailingTrivia {
229 &mut self.closing_trivia
230 }
231}
232
233impl Parse for Delimiter {
234 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
235 let group = parse_any_group(input, Self::expected())?;
236 if !group.stream().is_empty() {
237 return Err(TokenParseError::unexpected(
238 "an empty delimited group",
239 group.delim_kind().opening(),
240 group.expect_span(),
241 ));
242 }
243 Ok(group.delimiter().clone())
244 }
245}
246
247impl Lex for Delimiter {
248 fn to_tokens(&self, output: &mut TokenStream) {
249 self.surround(output, TokenStream::new());
250 }
251}
252
253#[doc(hidden)]
255pub fn parse_delimiter<D: DelimiterToken>(input: &mut ParseStream) -> Result<D, TokenParseError> {
256 let kind = D::KIND;
257 let group = parse_group(input, kind)?;
258 if !group.stream().is_empty() {
259 return Err(TokenParseError::unexpected(
260 kind.opening(),
261 kind.opening(),
262 group.expect_span(),
263 ));
264 }
265 Ok(D::new(group.delimiter().spans.clone()))
266}
267
268pub(crate) fn parse_group(
270 input: &mut ParseStream,
271 kind: DelimiterKind,
272) -> Result<TokenGroup, TokenParseError> {
273 let group = parse_any_group(input, kind.opening())?;
274 if group.delim_kind() != kind {
275 return Err(TokenParseError::unexpected(
276 kind.opening(),
277 group.delim_kind().opening(),
278 group.expect_span(),
279 ));
280 }
281 Ok(group)
282}
283
284pub(crate) fn parse_any_group(
286 input: &mut ParseStream,
287 expected: &'static str,
288) -> Result<TokenGroup, TokenParseError> {
289 let Some(token) = input.next_token() else {
290 return Err(TokenParseError::unexpected_end(expected, input.eof_span()));
291 };
292 let TokenTree::Group(group) = token else {
293 return Err(TokenParseError::unexpected_token(expected, &token));
294 };
295 Ok(group)
296}
297
298impl Display for Delimiter {
299 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
300 formatter.write_str(self.kind.opening())
301 }
302}
303impl Display for DelimiterKind {
304 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
305 formatter.write_str(self.opening())
306 }
307}
308
309impl DelimiterKind {
310 pub fn opening(self) -> &'static str {
312 match self {
313 Self::Parenthesis => "(",
314 Self::Bracket => "[",
315 Self::Brace => "{",
316 Self::AngleBar => "<|",
317 }
318 }
319
320 pub fn closing(self) -> &'static str {
322 match self {
323 Self::Parenthesis => ")",
324 Self::Bracket => "]",
325 Self::Brace => "}",
326 Self::AngleBar => "|>",
327 }
328 }
329}