use syn::Ident;
use super::prost_sanatize;
pub(crate) fn field_ident_from_str(s: impl AsRef<str>) -> Ident {
syn::parse_str(&prost_sanatize::to_snake(s.as_ref())).unwrap()
}
pub(crate) fn type_ident_from_str(s: impl AsRef<str>) -> Ident {
syn::parse_str(&prost_sanatize::to_upper_camel(s.as_ref())).unwrap()
}
pub(crate) fn get_common_import_path(package: &str, end: &str) -> syn::Path {
let start_parts: Vec<&str> = package.split('.').collect();
let mut end_parts: Vec<&str> = end.split('.').collect();
let end_part = type_ident_from_str(end_parts.pop().expect("end path must not be empty")).to_string();
let common_len = start_parts.iter().zip(&end_parts).take_while(|(a, b)| a == b).count();
let num_supers = start_parts.len().saturating_sub(common_len);
let mut path_parts = Vec::new();
for _ in 0..num_supers {
path_parts.push("super".to_string());
}
for end_part in end_parts[common_len..].iter() {
path_parts.push(field_ident_from_str(end_part).to_string());
}
path_parts.push(end_part);
syn::parse_str(&path_parts.join("::")).expect("failed to parse path")
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use quote::ToTokens;
use super::*;
#[test]
fn test_get_common_import_path() {
assert_eq!(
get_common_import_path("a.b.c", "a.b.d").to_token_stream().to_string(),
syn::parse_str::<syn::Path>("super::D").unwrap().to_token_stream().to_string()
);
assert_eq!(
get_common_import_path("a.b.c", "a.b.c.d").to_token_stream().to_string(),
syn::parse_str::<syn::Path>("D").unwrap().to_token_stream().to_string()
);
assert_eq!(
get_common_import_path("a.b.c", "a.b.c").to_token_stream().to_string(),
syn::parse_str::<syn::Path>("super::C").unwrap().to_token_stream().to_string()
);
assert_eq!(
get_common_import_path("a.b.c", "a.b").to_token_stream().to_string(),
syn::parse_str::<syn::Path>("super::super::B")
.unwrap()
.to_token_stream()
.to_string()
);
}
}