Skip to main content

typed_quote/tokens/
group.rs

1use super::*;
2
3#[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
4trait HasDelimiter<D> {
5    const DELIMITER: D;
6}
7
8crate::impl_many!({
9    {
10        {
11            use Parenthesis as G;
12            #[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
13            macro_rules! DELIMITER {
14                ($pm:ident) => {
15                    $pm::Delimiter::Parenthesis
16                };
17            }
18        }
19        {
20            use Bracket as G;
21            #[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
22            macro_rules! DELIMITER {
23                ($pm:ident) => {
24                    $pm::Delimiter::Bracket
25                };
26            }
27        }
28        {
29            use Brace as G;
30            #[cfg(any(feature = "proc-macro", feature = "proc-macro2"))]
31            macro_rules! DELIMITER {
32                ($pm:ident) => {
33                    $pm::Delimiter::Brace
34                };
35            }
36        }
37    }
38
39    #[cfg(feature = "proc-macro")]
40    impl HasDelimiter<proc_macro::Delimiter> for G<Empty> {
41        const DELIMITER: proc_macro::Delimiter = DELIMITER!(proc_macro);
42    }
43    #[cfg(feature = "proc-macro2")]
44    impl HasDelimiter<proc_macro2::Delimiter> for G<Empty> {
45        const DELIMITER: proc_macro2::Delimiter = DELIMITER!(proc_macro2);
46    }
47
48    impl<T: IntoTokens, S: MaybeSpan> sealed::IntoTokenTree for G<T, S> {}
49    impl<T: IntoTokens, S: MaybeSpan> IntoTokenTree for G<T, S> {
50        crate::impl_into_token_tree!(|self| pm::TokenTree::Group(
51            (
52                pm::Group::new(G::<Empty>::DELIMITER, self.stream.into_st()),
53                self.delimiter_span,
54            )
55                .into_st()
56        ));
57    }
58
59    impl<T: IntoTokens, S: MaybeSpan> sealed::IntoTokens for G<T, S> {}
60    impl<T: IntoTokens, S: MaybeSpan> IntoTokens for G<T, S> {
61        crate::impl_into_tokens! {tt}
62    }
63
64    impl<T: ToTokens, S: MaybeSpan> sealed::ToTokenTree for G<T, S> {}
65    impl<T: ToTokens, S: MaybeSpan> ToTokenTree for G<T, S> {
66        crate::impl_to_token_tree!(|self| pm::TokenTree::Group(
67            (
68                pm::Group::new(
69                    G::<Empty>::DELIMITER,
70                    <&T as IntoST<pm::TokenStream>>::into_st(&self.stream)
71                ),
72                self.delimiter_span
73            )
74                .into_st()
75        ));
76    }
77
78    impl<T: ToTokens, S: MaybeSpan> sealed::ToTokens for G<T, S> {}
79    impl<T: ToTokens, S: MaybeSpan> ToTokens for G<T, S> {
80        crate::impl_to_tokens! {tt}
81    }
82
83    impl<T: IntoTokens + WithSpan, SO: MaybeSpan> sealed::WithSpan for G<T, SO> {}
84    impl<T: IntoTokens + WithSpan, SO: MaybeSpan> WithSpan for G<T, SO> {
85        type WithDefaultSpan<S: crate::Span> = G<T::WithDefaultSpan<S>, SO::WithDefaultSpan<S>>;
86
87        fn with_default_span<S: crate::Span>(self, span: S) -> Self::WithDefaultSpan<S> {
88            G {
89                stream: self.stream.with_default_span(span),
90                delimiter_span: self.delimiter_span.with_default_span(span),
91            }
92        }
93
94        type WithReplacedSpan<S: crate::Span> = G<T::WithReplacedSpan<S>, SO::WithReplacedSpan<S>>;
95
96        fn with_replaced_span<S: crate::Span>(self, span: S) -> Self::WithReplacedSpan<S> {
97            G {
98                stream: self.stream.with_replaced_span(span),
99                delimiter_span: self.delimiter_span.with_replaced_span(span),
100            }
101        }
102    }
103
104    impl<T: IntoTokens + RefWithSpan, SO: MaybeSpan> sealed::RefWithSpan for G<T, SO> {}
105    impl<T: IntoTokens + RefWithSpan, SO: MaybeSpan> RefWithSpan for G<T, SO> {
106        type RefWithDefaultSpan<'a, S: crate::Span>
107            = G<T::RefWithDefaultSpan<'a, S>, SO::WithDefaultSpan<S>>
108        where
109            Self: 'a;
110
111        fn ref_with_default_span<S: crate::Span>(
112            &self,
113            span: S,
114        ) -> Self::RefWithDefaultSpan<'_, S> {
115            G {
116                stream: self.stream.ref_with_default_span(span),
117                delimiter_span: self.delimiter_span.with_default_span(span),
118            }
119        }
120
121        type RefWithReplacedSpan<'a, S: crate::Span>
122            = G<T::RefWithReplacedSpan<'a, S>, SO::WithReplacedSpan<S>>
123        where
124            Self: 'a;
125
126        fn ref_with_replaced_span<S: crate::Span>(
127            &self,
128            span: S,
129        ) -> Self::RefWithReplacedSpan<'_, S> {
130            G {
131                stream: self.stream.ref_with_replaced_span(span),
132                delimiter_span: self.delimiter_span.with_replaced_span(span),
133            }
134        }
135    }
136});
137
138#[cfg(test)]
139const _: () = {
140    #[cfg(feature = "proc-macro")]
141    {
142        assert!(matches!(
143            Parenthesis::DELIMITER,
144            proc_macro::Delimiter::Parenthesis
145        ));
146        assert!(matches!(Bracket::DELIMITER, proc_macro::Delimiter::Bracket));
147        assert!(matches!(Brace::DELIMITER, proc_macro::Delimiter::Brace));
148    }
149
150    #[cfg(feature = "proc-macro2")]
151    {
152        assert!(matches!(
153            Parenthesis::DELIMITER,
154            proc_macro2::Delimiter::Parenthesis
155        ));
156        assert!(matches!(
157            Bracket::DELIMITER,
158            proc_macro2::Delimiter::Bracket
159        ));
160        assert!(matches!(Brace::DELIMITER, proc_macro2::Delimiter::Brace));
161    }
162};