mod macros;
pub mod tools {
pub use {::proc_macro2, ::proc_macro_crate, ::quote, ::syn};
}
use proc_macro2::Span;
use proc_macro_crate::{crate_name, FoundCrate};
use quote::quote;
use syn::{Ident, LitStr};
pub fn quote_crate(found: FoundCrate) -> proc_macro2::TokenStream {
match found {
FoundCrate::Itself => quote! { crate },
FoundCrate::Name(name) => {
let ident = Ident::new(&name, Span::call_site());
quote! { #ident }
}
}
}
pub fn find_macroscope() -> proc_macro2::TokenStream {
quote_crate(crate_name("macroscope").unwrap())
}
pub fn find_crate(first: LitStr ) -> FoundCrate {
match crate_name(&first.value()) {
Ok(c) => return c,
Err(err) => panic!("{}", err),
}
}
#[allow(unused)]
enum FindResult<T, E, A> {
Found(T),
Failure { error: E, accumulated: A },
}
#[allow(unused)]
enum MapResult<T, E> {
Found(T),
Failure(E),
}
#[allow(unused)]
fn find<T, U, A, E>(
initial: A,
iterator: impl Iterator<Item = T>,
mapper: impl Fn(&mut A, &T, bool) -> MapResult<U, E>,
) -> FindResult<U, E, A> {
let mut iter = iterator.peekable();
let mut accum = initial;
while let Some(item) = iter.next() {
match mapper(&mut accum, &item, iter.peek().is_none()) {
MapResult::Found(found) => return FindResult::Found(found),
MapResult::Failure(error) if iter.peek().is_none() => {
return FindResult::Failure {
error,
accumulated: accum,
}
}
MapResult::Failure(_) => continue,
};
}
unreachable!("loop should reach iter.peek() == None at some point")
}