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,
168 closing_trivia: TrailingTrivia,
170}
171
172impl Delimiter {
173 pub fn new(kind: DelimiterKind, spans: DoubleSpan) -> Self {
175 Self {
176 kind,
177 spans,
178 opening_trivia: TrailingTrivia::default(),
179 closing_trivia: TrailingTrivia::default(),
180 }
181 }
182
183 pub fn opening_span(&self) -> Span {
185 self.spans.open()
186 }
187
188 pub fn closing_span(&self) -> Option<Span> {
190 self.spans.close()
191 }
192
193 pub fn is_closed(&self) -> bool {
195 self.spans.is_closed()
196 }
197}
198
199impl Spanned for Delimiter {
200 fn try_span(&self) -> Option<Span> {
201 self.spans.try_span()
202 }
203}
204
205impl DelimiterValue for Delimiter {
206 fn from_delimiter(delimiter: Delimiter) -> Option<Self> {
207 Some(delimiter)
208 }
209
210 fn delimiter(&self) -> Delimiter {
211 self.clone()
212 }
213
214 fn expected() -> &'static str {
215 "a delimited group"
216 }
217
218 fn opening_trivia(&self) -> &TrailingTrivia {
219 &self.opening_trivia
220 }
221
222 fn opening_trivia_mut(&mut self) -> &mut TrailingTrivia {
223 &mut self.opening_trivia
224 }
225
226 fn closing_trivia(&self) -> &TrailingTrivia {
227 &self.closing_trivia
228 }
229
230 fn closing_trivia_mut(&mut self) -> &mut TrailingTrivia {
231 &mut self.closing_trivia
232 }
233}
234
235impl Parse for Delimiter {
236 fn parse(input: &mut ParseStream) -> Result<Self, TokenParseError> {
237 let group = parse_any_group(input, Self::expected())?;
238 if !group.stream().is_empty() {
239 return Err(TokenParseError::unexpected(
240 "an empty delimited group",
241 group.delim_kind().opening(),
242 group.expect_span(),
243 ));
244 }
245 Ok(group.delimiter().clone())
246 }
247}
248
249impl Lex for Delimiter {
250 fn to_tokens(&self, output: &mut TokenStream) {
251 self.surround(output, TokenStream::new());
252 }
253}
254
255#[doc(hidden)]
257pub fn parse_delimiter<D: DelimiterToken>(input: &mut ParseStream) -> Result<D, TokenParseError> {
258 let kind = D::KIND;
259 let group = parse_group(input, kind)?;
260 if !group.stream().is_empty() {
261 return Err(TokenParseError::unexpected(
262 kind.opening(),
263 kind.opening(),
264 group.expect_span(),
265 ));
266 }
267 Ok(D::new(group.delimiter().spans.clone()))
268}
269
270pub(crate) fn parse_group(
272 input: &mut ParseStream,
273 kind: DelimiterKind,
274) -> Result<TokenGroup, TokenParseError> {
275 let group = parse_any_group(input, kind.opening())?;
276 if group.delim_kind() != kind {
277 return Err(TokenParseError::unexpected(
278 kind.opening(),
279 group.delim_kind().opening(),
280 group.expect_span(),
281 ));
282 }
283 Ok(group)
284}
285
286pub(crate) fn parse_any_group(
288 input: &mut ParseStream,
289 expected: &'static str,
290) -> Result<TokenGroup, TokenParseError> {
291 let Some(token) = input.next_token() else {
292 return Err(TokenParseError::unexpected_end(expected, input.eof_span()));
293 };
294 let TokenTree::Group(group) = token else {
295 return Err(TokenParseError::unexpected_token(expected, &token));
296 };
297 Ok(group)
298}
299
300impl Display for Delimiter {
301 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
302 formatter.write_str(self.kind.opening())
303 }
304}
305impl Display for DelimiterKind {
306 fn fmt(&self, formatter: &mut Formatter<'_>) -> std::fmt::Result {
307 formatter.write_str(self.opening())
308 }
309}
310
311impl DelimiterKind {
312 pub fn opening(self) -> &'static str {
314 match self {
315 Self::Parenthesis => "(",
316 Self::Bracket => "[",
317 Self::Brace => "{",
318 Self::AngleBar => "<|",
319 }
320 }
321
322 pub fn closing(self) -> &'static str {
324 match self {
325 Self::Parenthesis => ")",
326 Self::Bracket => "]",
327 Self::Brace => "}",
328 Self::AngleBar => "|>",
329 }
330 }
331}