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 PunctuatedItems<T: Parse> {
81 pub inner: Vec<T>,
82}
83
84impl<T: Parse> Parse for PunctuatedItems<T> {
85 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
86 let inner = Punctuated::<T, Token![,]>::parse_terminated(input)?
87 .into_iter()
88 .collect();
89
90 Ok(Self { inner })
91 }
92}
93
94pub struct StringList {
95 pub list: Vec<String>,
96}
97
98impl Parse for StringList {
99 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
100 let items = Punctuated::<LitStr, Token![,]>::parse_terminated(input)?;
101
102 let list: Vec<String> = items
103 .into_iter()
104 .map(|lit_str| lit_str.value())
105 .collect();
106
107 Ok(Self { list })
108 }
109}
110
111pub struct NumList {
112 pub list: Vec<i32>,
113}
114
115impl Parse for NumList {
116 fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
117 let items = Punctuated::<LitInt, Token![,]>::parse_terminated(input)?;
118
119 let mut list: Vec<i32> = Vec::new();
120
121 for item in items {
122 list.push(item.base10_parse()?);
123 }
124
125 Ok(Self { list })
126 }
127}