tinc_build/codegen/
utils.rs1use syn::Ident;
2
3use super::prost_sanatize;
4
5pub(crate) fn field_ident_from_str(s: impl AsRef<str>) -> Ident {
6 syn::parse_str(&prost_sanatize::to_snake(s.as_ref())).unwrap()
7}
8
9pub(crate) fn type_ident_from_str(s: impl AsRef<str>) -> Ident {
10 syn::parse_str(&prost_sanatize::to_upper_camel(s.as_ref())).unwrap()
11}
12
13pub(crate) fn get_common_import_path(package: &str, end: &str) -> syn::Path {
14 let start_parts: Vec<&str> = package.split('.').collect();
15 let mut end_parts: Vec<&str> = end.split('.').collect();
16
17 let end_part = type_ident_from_str(end_parts.pop().expect("end path must not be empty")).to_string();
18
19 let common_len = start_parts.iter().zip(&end_parts).take_while(|(a, b)| a == b).count();
20
21 let num_supers = start_parts.len().saturating_sub(common_len);
22
23 let mut path_parts = Vec::new();
24
25 for _ in 0..num_supers {
26 path_parts.push("super".to_string());
27 }
28
29 for end_part in end_parts[common_len..].iter() {
30 path_parts.push(field_ident_from_str(end_part).to_string());
31 }
32
33 path_parts.push(end_part);
34
35 syn::parse_str(&path_parts.join("::")).expect("failed to parse path")
36}
37
38#[cfg(test)]
39#[cfg_attr(coverage_nightly, coverage(off))]
40mod tests {
41 use quote::ToTokens;
42
43 use super::*;
44
45 #[test]
46 fn test_get_common_import_path() {
47 assert_eq!(
48 get_common_import_path("a.b.c", "a.b.d").to_token_stream().to_string(),
49 syn::parse_str::<syn::Path>("super::D").unwrap().to_token_stream().to_string()
50 );
51 assert_eq!(
52 get_common_import_path("a.b.c", "a.b.c.d").to_token_stream().to_string(),
53 syn::parse_str::<syn::Path>("D").unwrap().to_token_stream().to_string()
54 );
55 assert_eq!(
56 get_common_import_path("a.b.c", "a.b.c").to_token_stream().to_string(),
57 syn::parse_str::<syn::Path>("super::C").unwrap().to_token_stream().to_string()
58 );
59 assert_eq!(
60 get_common_import_path("a.b.c", "a.b").to_token_stream().to_string(),
61 syn::parse_str::<syn::Path>("super::super::B")
62 .unwrap()
63 .to_token_stream()
64 .to_string()
65 );
66 }
67}