zng_ext_l10n_proc_macros/
util.rs
1use proc_macro2::{Span, TokenStream};
2use quote::{ToTokens, quote_spanned};
3
4#[derive(Default)]
6pub struct Errors {
7 tokens: TokenStream,
8}
9impl Errors {
10 pub fn push(&mut self, error: impl ToString, span: Span) {
12 let error = error.to_string();
13 self.tokens.extend(quote_spanned! {span=>
14 compile_error!{#error}
15 })
16 }
17
18 pub fn is_empty(&self) -> bool {
19 self.tokens.is_empty()
20 }
21}
22impl ToTokens for Errors {
23 fn to_tokens(&self, tokens: &mut TokenStream) {
24 tokens.extend(self.tokens.clone())
25 }
26 fn to_token_stream(&self) -> TokenStream {
27 self.tokens.clone()
28 }
29 fn into_token_stream(self) -> TokenStream {
30 self.tokens
31 }
32}
33
34macro_rules! non_user_error {
36 ($e:expr) => {
37 panic!("[{}:{}] invalid non-user input: {}", file!(), line!(), $e)
38 };
39 ($fmt:tt, $($args:tt)+) => {
40 non_user_error! {
41 format_args!($fmt, $($args)+)
42 }
43 }
44}
45
46macro_rules! ident_spanned {
48 ($span:expr=> $($format_name:tt)+) => {
49 proc_macro2::Ident::new(&format!($($format_name)+), $span)
50 };
51}
52
53macro_rules! non_user_group {
54 ($group_kind:ident, $input:expr) => {
55 {
56 fn inner(input: syn::parse::ParseStream) -> syn::Result<syn::parse::ParseBuffer> {
57 let inner;
58 syn::$group_kind!(inner in input);
60 Ok(inner)
61 }
62 inner($input).unwrap_or_else(|e| non_user_error!(e))
63 }
64 };
65 ($group_kind:ident, $input:expr, $ident:expr) => {
66 {
67 let id: syn::Ident = $input.parse().unwrap_or_else(|e| non_user_error!(e));
68 let ident = $ident;
69 if id != ident {
70 non_user_error!(format!("expected `{ident}`"));
71 }
72 non_user_group! { $group_kind, $input }
73 }
74 }
75}
76macro_rules! non_user_braced {
78 ($input:expr) => {
79 non_user_group! { braced, $input }
80 };
81 ($input:expr, $ident:expr) => {
82 non_user_group! { braced, $input, $ident }
83 };
84}