1use macroex::{proc_macro2::{TokenStream, TokenTree, Delimiter}, FromMacro, StreamExtract, All};
4use quote::ToTokens;
5
6mod angle;
7mod color;
8
9pub use angle::Angle;
10pub use color::Rgba;
11
12#[derive(Debug, Clone, Default)]
15pub enum MaybeExpr<T, TExpr=TokenStream>{
16 #[default]
17 None,
18 Value(T),
19 Expr(TExpr),
20}
21
22impl<T, TExpr> MaybeExpr<T, TExpr> {
23 pub fn is_some(&self) -> bool {
24 !matches!(self, MaybeExpr::None)
25 }
26
27 pub fn is_none(&self) -> bool {
28 matches!(self, MaybeExpr::None)
29 }
30
31 pub fn get(&self) -> Option<ValueOrExpr<T, TExpr>> {
32 match self {
33 MaybeExpr::None => None,
34 MaybeExpr::Expr(e) => Some(ValueOrExpr::Expr(e)),
35 MaybeExpr::Value(v) => Some(ValueOrExpr::Value(v)),
36 }
37 }
38}
39
40
41impl<T: FromMacro, TExpr: FromMacro> FromMacro for MaybeExpr<T, TExpr> {
42 fn from_one(tt: macroex::proc_macro2::TokenTree) -> Result<Self, macroex::Error> {
43 match tt {
44 TokenTree::Group(ref g) if g.delimiter() == Delimiter::Brace => {
45 let All(expr) = g.stream().into_iter().extract()?;
46 Ok(Self::Expr(expr))
47 },
48 tt => Ok(Self::Value(T::from_one(tt)?))
49 }
50 }
51}
52
53#[derive(Debug, Clone)]
54pub enum ValueOrExpr<'t, T, TExpr=TokenStream>{
55 Value(&'t T),
56 Expr(&'t TExpr),
57}
58
59
60impl<T: ToTokens, TExpr: ToTokens> quote::ToTokens for ValueOrExpr<'_, T, TExpr> {
61 fn to_tokens(&self, tokens: &mut TokenStream) {
62 match self {
63 ValueOrExpr::Value(v) => v.to_tokens(tokens),
64 ValueOrExpr::Expr(t) => t.to_tokens(tokens),
65 }
66 }
67}