1#[macro_use]
2mod macros;
3
4mod expr_trait;
5use std::{fmt::Display, str::FromStr};
6
7pub use expr_trait::*;
8use proc_macro2::{Span, TokenStream as TokenStream2};
9use quote::{quote, ToTokens};
10use syn::{
11 parse::Parse, punctuated::Punctuated, Expr, ExprCall, ExprClosure, Ident, Lit, LitInt, LitStr,
12 Path, Token,
13};
14
15pub fn new_ident(name: &str) -> Ident {
16 Ident::new(name, Span::call_site())
17}
18
19#[derive(Default, Clone, Debug)]
20pub struct ControlFlow {
21 pub dummy: Option<TokenStream2>,
22}
23
24impl ControlFlow {
25 pub fn new() -> Self {
26 Self { dummy: None }
27 }
28
29 pub fn with_custom_dummy(dummy: &TokenStream2) -> Self {
30 Self {
31 dummy: Some(dummy.to_token_stream()),
32 }
33 }
34}
35
36pub trait MacroResult: Sized {
37 type Output;
38
39 fn unwrap_or_dummy(self, dummy: TokenStream2) -> Result<Self::Output, TokenStream2>;
40
41 fn unwrap_or_unimplemented(self) -> Result<Self::Output, TokenStream2> {
42 self.unwrap_or_dummy(quote! { unimplemented!() })
43 }
44}
45
46impl<T> MacroResult for syn::Result<T> {
47 type Output = T;
48
49 fn unwrap_or_dummy(self, dummy: TokenStream2) -> Result<Self::Output, TokenStream2> {
50 match self {
51 Ok(o) => Ok(o),
52 Err(e) => {
53 let error = e.into_compile_error();
54
55 Err(quote! {
56 #error #dummy
57 })
58 }
59 }
60 }
61}
62
63#[derive(Debug, Clone)]
64pub enum CallOrClosure {
65 Call(ExprCall),
66 Closure(ExprClosure),
67}
68
69impl ToTokens for CallOrClosure {
70 fn to_tokens(&self, tokens: &mut TokenStream2) {
71 let output = match self {
72 CallOrClosure::Call(call) => call.to_token_stream(),
73 CallOrClosure::Closure(expr_closure) => expr_closure.to_token_stream(),
74 };
75
76 tokens.extend(output);
77 }
78}
79
80pub struct PunctuatedParser<T: Parse> {
81 pub inner: Punctuated<T, Token![,]>,
82}
83
84impl<T: Parse> Parse for PunctuatedParser<T> {
85 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
86 let inner = Punctuated::parse_terminated(input)?;
87
88 Ok(Self { inner })
89 }
90}
91
92pub struct StringList {
93 pub list: Vec<String>,
94}
95
96impl Parse for StringList {
97 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
98 let items = Punctuated::<LitStr, Token![,]>::parse_terminated(input)?;
99
100 let list: Vec<String> = items
101 .into_iter()
102 .map(|lit_str| lit_str.value())
103 .collect();
104
105 Ok(Self { list })
106 }
107}
108
109pub struct NumList {
110 pub list: Vec<i32>,
111}
112
113impl Parse for NumList {
114 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
115 let items = Punctuated::<LitInt, Token![,]>::parse_terminated(input)?;
116
117 let mut list: Vec<i32> = Vec::new();
118
119 for item in items {
120 list.push(item.base10_parse()?);
121 }
122
123 Ok(Self { list })
124 }
125}