wayland_scanner/
util.rs

1use proc_macro2::{Ident, Span, TokenStream};
2use quote::{quote, ToTokens};
3
4pub(crate) fn to_doc_attr(text: &str) -> TokenStream {
5    let text = text.lines().map(str::trim).collect::<Vec<_>>().join("\n");
6    let text = text.trim();
7
8    quote!(#[doc = #text])
9}
10
11pub(crate) fn description_to_doc_attr((short, long): &(String, String)) -> TokenStream {
12    to_doc_attr(&format!("{}\n\n{}", short, long))
13}
14
15pub fn is_keyword(txt: &str) -> bool {
16    matches!(
17        txt,
18        "abstract"
19            | "alignof"
20            | "as"
21            | "become"
22            | "box"
23            | "break"
24            | "const"
25            | "continue"
26            | "crate"
27            | "do"
28            | "else"
29            | "enum"
30            | "extern"
31            | "false"
32            | "final"
33            | "fn"
34            | "for"
35            | "if"
36            | "impl"
37            | "in"
38            | "let"
39            | "loop"
40            | "macro"
41            | "match"
42            | "mod"
43            | "move"
44            | "mut"
45            | "offsetof"
46            | "override"
47            | "priv"
48            | "proc"
49            | "pub"
50            | "pure"
51            | "ref"
52            | "return"
53            | "Self"
54            | "self"
55            | "sizeof"
56            | "static"
57            | "struct"
58            | "super"
59            | "trait"
60            | "true"
61            | "type"
62            | "typeof"
63            | "unsafe"
64            | "unsized"
65            | "use"
66            | "virtual"
67            | "where"
68            | "while"
69            | "yield"
70            | "__handler"
71            | "__object"
72    )
73}
74
75pub fn is_camel_keyword(txt: &str) -> bool {
76    matches!(txt, "Self")
77}
78
79pub fn snake_to_camel(input: &str) -> String {
80    let result = input
81        .split('_')
82        .flat_map(|s| {
83            let mut first = true;
84            s.chars().map(move |c| {
85                if first {
86                    first = false;
87                    c.to_ascii_uppercase()
88                } else {
89                    c
90                }
91            })
92        })
93        .collect::<String>();
94
95    if is_camel_keyword(&result) {
96        format!("_{}", &result)
97    } else {
98        result
99    }
100}
101
102pub fn dotted_to_relname(input: &str) -> TokenStream {
103    let mut it = input.split('.');
104    match (it.next(), it.next()) {
105        (Some(module), Some(name)) => {
106            let module = Ident::new(module, Span::call_site());
107            let ident = Ident::new(&snake_to_camel(name), Span::call_site());
108            quote::quote!(super::#module::#ident)
109        }
110        (Some(name), None) => {
111            Ident::new(&snake_to_camel(name), Span::call_site()).into_token_stream()
112        }
113        _ => unreachable!(),
114    }
115}