use crate::{
error::Error,
token_iter::{is_ident, SubGroupIter},
Result, SubstitutionGroup, TokenIter,
};
use heck::ToSnakeCase;
use proc_macro::{Ident, Span, TokenStream, TokenTree};
pub(crate) fn find_simple<'a>(
substitutions: impl Iterator<Item = &'a SubstitutionGroup> + Clone,
mod_span: Span,
) -> Result<String>
{
let mut substitutions = substitutions.peekable();
if substitutions.peek().is_none()
{
return Ok("".into());
}
'outer: for ident in substitutions.peek().unwrap().identifiers_ordered()
{
for group in substitutions.clone()
{
let substitution = group.substitution_of(ident).unwrap();
if substitution.substitutes_identifier().is_none()
{
continue 'outer;
}
}
return Ok(ident.clone());
}
Err(Error::new(
"Was unable to find a suitable substitution identifier to postfix on the module's \
name.\nHint: If a substitution identifier's substitutions all consist of a single \
identifier and nothing, they will automatically be postfixed on the module name to make \
them unique.",
)
.span(mod_span))
}
pub(crate) fn try_substitute_mod<'a, T: SubGroupIter<'a>>(
mod_and_postfix_sub: &Option<(Ident, String)>,
substitutions: &SubstitutionGroup,
item_iter: &mut TokenIter<'a, T>,
) -> TokenStream
{
let mut result = TokenStream::new();
if let Some((mod_name, mod_sub_ident)) = mod_and_postfix_sub
{
item_iter
.extract_simple(|t| is_ident(t, Some("mod")), |t| t, None)
.map_or((), |mod_keyword| {
result.extend(Some(mod_keyword).into_iter());
let mod_name_t = item_iter.next_fallible().unwrap().unwrap();
let postfix = substitutions
.substitution_of(&mod_sub_ident)
.unwrap()
.substitutes_identifier()
.unwrap()
.to_string()
.to_snake_case();
let replacement_name = mod_name.to_string() + "_" + &postfix;
let replacement = Ident::new(&replacement_name, TokenTree::from(mod_name_t).span());
result.extend(Some(TokenTree::Ident(replacement)).into_iter());
});
}
result
}