1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
/*
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/.
 */

//! Allowed expressions.

use proc_macro2::Span;

/// Convert to a variety of source-code-related formats.
pub trait Expression: core::fmt::Debug {
    /// Convert `&Self -> syn::Expr`.
    #[must_use]
    fn to_expr(&self) -> syn::Expr;
    /// Convert `&Self -> syn::Pat`.
    #[must_use]
    fn to_pattern(&self) -> syn::Pat;
    /// Write a `syn::Type` type representing this value's type.
    #[must_use]
    fn to_type() -> syn::Type;
}

impl Expression for char {
    #[inline]
    fn to_expr(&self) -> syn::Expr {
        syn::Expr::Lit(syn::ExprLit {
            attrs: vec![],
            lit: syn::Lit::Char(syn::LitChar::new(*self, Span::call_site())),
        })
    }
    #[inline]
    fn to_pattern(&self) -> syn::Pat {
        syn::Pat::Lit(syn::ExprLit {
            attrs: vec![],
            lit: syn::Lit::Char(syn::LitChar::new(*self, Span::call_site())),
        })
    }
    #[inline]
    fn to_type() -> syn::Type {
        syn::Type::Path(syn::TypePath {
            qself: None,
            path: syn::Path {
                leading_colon: None,
                segments: core::iter::once(syn::PathSegment {
                    ident: syn::Ident::new("char", Span::call_site()),
                    arguments: syn::PathArguments::None,
                })
                .collect(),
            },
        })
    }
}

impl Expression for u8 {
    #[inline]
    fn to_expr(&self) -> syn::Expr {
        syn::Expr::Lit(syn::ExprLit {
            attrs: vec![],
            lit: syn::Lit::Byte(syn::LitByte::new(*self, Span::call_site())),
        })
    }
    #[inline]
    fn to_pattern(&self) -> syn::Pat {
        syn::Pat::Lit(syn::ExprLit {
            attrs: vec![],
            lit: syn::Lit::Byte(syn::LitByte::new(*self, Span::call_site())),
        })
    }
    #[inline]
    fn to_type() -> syn::Type {
        syn::Type::Path(syn::TypePath {
            qself: None,
            path: syn::Path {
                leading_colon: None,
                segments: core::iter::once(syn::PathSegment {
                    ident: syn::Ident::new("u8", Span::call_site()),
                    arguments: syn::PathArguments::None,
                })
                .collect(),
            },
        })
    }
}