synkit_core/delimited.rs
1use crate::traits::SpanLike;
2
3/// A value enclosed by delimiters (e.g., brackets, braces, parentheses).
4///
5/// Stores the combined span of the delimiters and the inner content.
6/// Use this to represent constructs like `[items]`, `{block}`, or `(expr)`.
7///
8/// # Type Parameters
9///
10/// - `T`: The inner content type
11/// - `Span`: The span type for source positions
12///
13/// # Example
14///
15/// ```ignore
16/// // Parse: [1, 2, 3]
17/// let bracket = bracket!(inner in stream);
18/// // `inner` is a TokenStream of "1, 2, 3"
19/// // `bracket` is Delimited with span covering "[...]"
20/// let items: Punctuated<Expr, Comma> = inner.parse()?;
21/// ```
22#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
23#[derive(Debug, Clone, PartialEq)]
24pub struct Delimited<T, Span> {
25 /// The span covering the entire delimited region (including delimiters).
26 pub span: Span,
27 /// The inner content between the delimiters.
28 pub inner: T,
29}
30
31impl<T, Span: SpanLike> Delimited<T, Span> {
32 #[inline]
33 pub fn new(span: Span, inner: T) -> Self {
34 Self { span, inner }
35 }
36
37 #[inline]
38 pub fn call_site(inner: T) -> Self {
39 Self {
40 span: Span::call_site(),
41 inner,
42 }
43 }
44
45 #[inline]
46 pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> Delimited<U, Span> {
47 Delimited {
48 span: self.span,
49 inner: f(self.inner),
50 }
51 }
52}
53
54impl<T, Span> std::ops::Deref for Delimited<T, Span> {
55 type Target = T;
56
57 #[inline]
58 fn deref(&self) -> &Self::Target {
59 &self.inner
60 }
61}
62
63impl<T, Span> std::ops::DerefMut for Delimited<T, Span> {
64 #[inline]
65 fn deref_mut(&mut self) -> &mut Self::Target {
66 &mut self.inner
67 }
68}