Skip to main content

typed_quote/tokens/
either.rs

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