]>
Commit | Line | Data |
---|---|---|
3b2f2976 XL |
1 | // Copyright 2017 Serde Developers |
2 | // | |
3 | // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | |
4 | // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | |
5 | // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | |
6 | // option. This file may not be copied, modified, or distributed | |
7 | // except according to those terms. | |
8 | ||
8faf50e0 XL |
9 | use proc_macro2::TokenStream; |
10 | use quote::ToTokens; | |
0531ce1d | 11 | use syn::token; |
3b2f2976 XL |
12 | |
13 | pub enum Fragment { | |
14 | /// Tokens that can be used as an expression. | |
8faf50e0 | 15 | Expr(TokenStream), |
3b2f2976 XL |
16 | /// Tokens that can be used inside a block. The surrounding curly braces are |
17 | /// not part of these tokens. | |
8faf50e0 | 18 | Block(TokenStream), |
3b2f2976 XL |
19 | } |
20 | ||
21 | macro_rules! quote_expr { | |
22 | ($($tt:tt)*) => { | |
23 | $crate::fragment::Fragment::Expr(quote!($($tt)*)) | |
24 | } | |
25 | } | |
26 | ||
27 | macro_rules! quote_block { | |
28 | ($($tt:tt)*) => { | |
29 | $crate::fragment::Fragment::Block(quote!($($tt)*)) | |
30 | } | |
31 | } | |
32 | ||
33 | /// Interpolate a fragment in place of an expression. This involves surrounding | |
34 | /// Block fragments in curly braces. | |
35 | pub struct Expr(pub Fragment); | |
36 | impl ToTokens for Expr { | |
8faf50e0 | 37 | fn to_tokens(&self, out: &mut TokenStream) { |
3b2f2976 XL |
38 | match self.0 { |
39 | Fragment::Expr(ref expr) => expr.to_tokens(out), | |
40 | Fragment::Block(ref block) => { | |
0531ce1d | 41 | token::Brace::default().surround(out, |out| block.to_tokens(out)); |
3b2f2976 XL |
42 | } |
43 | } | |
44 | } | |
45 | } | |
46 | ||
47 | /// Interpolate a fragment as the statements of a block. | |
48 | pub struct Stmts(pub Fragment); | |
49 | impl ToTokens for Stmts { | |
8faf50e0 | 50 | fn to_tokens(&self, out: &mut TokenStream) { |
3b2f2976 XL |
51 | match self.0 { |
52 | Fragment::Expr(ref expr) => expr.to_tokens(out), | |
53 | Fragment::Block(ref block) => block.to_tokens(out), | |
54 | } | |
55 | } | |
56 | } | |
57 | ||
58 | /// Interpolate a fragment as the value part of a `match` expression. This | |
59 | /// involves putting a comma after expressions and curly braces around blocks. | |
60 | pub struct Match(pub Fragment); | |
61 | impl ToTokens for Match { | |
8faf50e0 | 62 | fn to_tokens(&self, out: &mut TokenStream) { |
3b2f2976 XL |
63 | match self.0 { |
64 | Fragment::Expr(ref expr) => { | |
65 | expr.to_tokens(out); | |
0531ce1d | 66 | <Token![,]>::default().to_tokens(out); |
3b2f2976 XL |
67 | } |
68 | Fragment::Block(ref block) => { | |
0531ce1d | 69 | token::Brace::default().surround(out, |out| block.to_tokens(out)); |
3b2f2976 XL |
70 | } |
71 | } | |
72 | } | |
73 | } | |
ff7c6d11 | 74 | |
8faf50e0 XL |
75 | impl AsRef<TokenStream> for Fragment { |
76 | fn as_ref(&self) -> &TokenStream { | |
ff7c6d11 XL |
77 | match *self { |
78 | Fragment::Expr(ref expr) => expr, | |
79 | Fragment::Block(ref block) => block, | |
80 | } | |
81 | } | |
82 | } |