1mod macros;
2
3pub mod tools {
4 pub use {::proc_macro2, ::proc_macro_crate, ::quote, ::syn};
5}
6
7use proc_macro2::Span;
8use proc_macro_crate::{crate_name, FoundCrate};
9use quote::quote;
10use syn::{Ident, LitStr};
11
12pub fn quote_crate(found: FoundCrate) -> proc_macro2::TokenStream {
13 match found {
14 FoundCrate::Itself => quote! { crate },
15 FoundCrate::Name(name) => {
16 let ident = Ident::new(&name, Span::call_site());
17 quote! { #ident }
18 }
19 }
20}
21
22pub fn find_macroscope() -> proc_macro2::TokenStream {
23 quote_crate(crate_name("macroscope").unwrap())
24}
25
26pub fn find_crate(first: LitStr ) -> FoundCrate {
27 match crate_name(&first.value()) {
28 Ok(c) => return c,
29 Err(err) => panic!("{}", err),
30 }
31
32 }
61
62#[allow(unused)]
63enum FindResult<T, E, A> {
64 Found(T),
65 Failure { error: E, accumulated: A },
66}
67
68#[allow(unused)]
69enum MapResult<T, E> {
70 Found(T),
71 Failure(E),
72}
73
74#[allow(unused)]
75fn find<T, U, A, E>(
76 initial: A,
77 iterator: impl Iterator<Item = T>,
78 mapper: impl Fn(&mut A, &T, bool) -> MapResult<U, E>,
79) -> FindResult<U, E, A> {
80 let mut iter = iterator.peekable();
81 let mut accum = initial;
82
83 while let Some(item) = iter.next() {
84 match mapper(&mut accum, &item, iter.peek().is_none()) {
85 MapResult::Found(found) => return FindResult::Found(found),
86 MapResult::Failure(error) if iter.peek().is_none() => {
87 return FindResult::Failure {
88 error,
89 accumulated: accum,
90 }
91 }
92 MapResult::Failure(_) => continue,
93 };
94 }
95
96 unreachable!("loop should reach iter.peek() == None at some point")
97}