use crate::*;
pub(crate) fn parse_ident_segment(input: ParseStream) -> SynResult<String> {
let tt: proc_macro2::TokenTree = input.parse()?;
match tt {
proc_macro2::TokenTree::Ident(ident) => {
let raw: String = ident.to_string();
Ok(raw.strip_prefix("r#").unwrap_or(&raw).to_string())
}
_ => Err(input.error("expected identifier")),
}
}
pub(crate) fn parse_kebab_name(input: ParseStream) -> SynResult<String> {
if input.peek(LitStr) {
let lit: LitStr = input.parse()?;
return Ok(lit.value());
}
let first: String = parse_ident_segment(input)?;
let mut name: String = first;
while input.peek(Token![-]) {
input.parse::<Token![-]>()?;
let next: String = parse_ident_segment(input)?;
name.push('-');
name.push_str(&next);
}
Ok(name)
}
pub(crate) fn reconstruct_kebab_from_tokens(tokens: &TokenStream2) -> String {
let iter: std::iter::Peekable<proc_macro2::token_stream::IntoIter> =
tokens.clone().into_iter().peekable();
let mut parts: Vec<String> = Vec::new();
for token in iter {
match token {
proc_macro2::TokenTree::Ident(ident) => {
let raw: String = ident.to_string();
let clean: String = raw.strip_prefix("r#").unwrap_or(&raw).to_string();
parts.push(clean);
}
proc_macro2::TokenTree::Punct(punct) if punct.as_char() == '-' => {
continue;
}
proc_macro2::TokenTree::Group(group) => {
let inner: String = reconstruct_kebab_from_tokens(&group.stream());
parts.push(inner);
}
proc_macro2::TokenTree::Literal(lit) => {
let lit_ts: TokenStream2 = proc_macro2::TokenTree::Literal(lit).into();
if let Ok(lit_str) = syn::parse2::<LitStr>(lit_ts) {
parts.push(lit_str.value());
}
}
_ => {}
}
}
parts.join("-")
}