1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
use proc_macro2::Span as Span2;
use syn::{punctuated::Punctuated, token::Colon2, Ident, Path, PathArguments, PathSegment, Token};
macro_rules! parse_func {
($name:ident, $func:ident, $tokens:ident) => {
if $name.is_some() {
return Err(::syn::Error::new(
$func.span().unwrap().into(),
&format!("Method `{}` defined multiple times", stringify!($name)),
));
}
$name = Some($tokens);
};
}
pub(crate) fn idents_to_snake_case(idents: &[Ident], span: Span2) -> Ident {
use std::sync::atomic::{AtomicU16, Ordering};
static COUNTER: AtomicU16 = AtomicU16::new(0);
let val = COUNTER.fetch_add(1, Ordering::Relaxed);
let index_str = val.to_string();
let segements: Vec<String> = idents
.iter()
.map(|ident| ident.to_string().to_lowercase())
.collect();
let length: usize =
segements.iter().map(|seg| seg.len() + 1).sum::<usize>() + index_str.len() + 1;
let mut name: String = String::with_capacity(length);
for seg in &segements {
name.push('_');
name.push_str(seg);
}
name.push('_');
name.push_str(&index_str);
Ident::new(&name, span)
}
pub(crate) fn default_relm4_path() -> Path {
let relm4_path_segment = PathSegment {
ident: Ident::new("relm4", Span2::call_site()),
arguments: PathArguments::None,
};
let mut relm4_segments: Punctuated<PathSegment, Colon2> = Punctuated::new();
relm4_segments.push(relm4_path_segment);
Path {
leading_colon: Some(Token![::](Span2::call_site())),
segments: relm4_segments,
}
}