turbo_tasks_macros_shared/
ident.rs

1use quote::ToTokens;
2use syn::{GenericArgument, Ident, Path, PathArguments, Type, TypeParamBound, spanned::Spanned};
3
4pub fn get_cast_to_fat_pointer_ident(trait_ident: &Ident, struct_ident: &Ident) -> Ident {
5    Ident::new(
6        &format!("_cast_to_fat_pointer_{struct_ident}_{trait_ident}"),
7        trait_ident.span(),
8    )
9}
10
11pub fn get_native_function_ident(ident: &Ident) -> Ident {
12    Ident::new(
13        &format!("{}_FUNCTION", ident.to_string().to_uppercase()),
14        ident.span(),
15    )
16}
17
18pub fn get_trait_type_ident(ident: &Ident) -> Ident {
19    Ident::new(
20        &format!("{}_TRAIT_TYPE", ident.to_string().to_uppercase()),
21        ident.span(),
22    )
23}
24
25pub fn get_impl_function_ident(struct_ident: &Ident, ident: &Ident) -> Ident {
26    Ident::new(
27        &format!(
28            "{}_IMPL_{}_FUNCTION",
29            struct_ident.to_string().to_uppercase(),
30            ident.to_string().to_uppercase()
31        ),
32        ident.span(),
33    )
34}
35
36pub fn get_inherent_impl_function_ident(ty_ident: &Ident, fn_ident: &Ident) -> Ident {
37    Ident::new(
38        &format!(
39            "{}_IMPL_{}_FUNCTION",
40            ty_ident.to_string().to_uppercase(),
41            fn_ident.to_string().to_uppercase()
42        ),
43        fn_ident.span(),
44    )
45}
46
47pub fn get_inherent_impl_function_id_ident(ty_ident: &Ident, fn_ident: &Ident) -> Ident {
48    Ident::new(
49        &format!(
50            "{}_IMPL_{}_FUNCTION_ID",
51            ty_ident.to_string().to_uppercase(),
52            fn_ident.to_string().to_uppercase()
53        ),
54        fn_ident.span(),
55    )
56}
57
58pub fn get_trait_impl_function_ident(
59    struct_ident: &Ident,
60    trait_ident: &Ident,
61    ident: &Ident,
62) -> Ident {
63    Ident::new(
64        &format!(
65            "{}_IMPL_TRAIT_{}_{}_FUNCTION",
66            struct_ident.to_string().to_uppercase(),
67            trait_ident.to_string().to_uppercase(),
68            ident.to_string().to_uppercase()
69        ),
70        ident.span(),
71    )
72}
73
74pub fn get_trait_impl_function_id_ident(
75    struct_ident: &Ident,
76    trait_ident: &Ident,
77    ident: &Ident,
78) -> Ident {
79    Ident::new(
80        &format!(
81            "{}_IMPL_TRAIT_{}_{}_FUNCTION_ID",
82            struct_ident.to_string().to_uppercase(),
83            trait_ident.to_string().to_uppercase(),
84            ident.to_string().to_uppercase()
85        ),
86        ident.span(),
87    )
88}
89
90pub fn get_path_ident(path: &Path) -> Ident {
91    let mut result = String::new();
92
93    for (i, segment) in path.segments.iter().enumerate() {
94        let ident = segment.ident.to_string();
95
96        if i > 0 {
97            result.push('_');
98        }
99
100        result.push_str(&ident);
101
102        match &segment.arguments {
103            PathArguments::AngleBracketed(args) => {
104                for arg in &args.args {
105                    match arg {
106                        GenericArgument::Type(ty) => {
107                            if let Type::Path(type_path) = ty {
108                                let type_ident = get_path_ident(&type_path.path);
109                                result.push('_');
110                                result.push_str(&type_ident.to_string());
111                            } else if let Type::TraitObject(trait_obj) = ty {
112                                for bound in &trait_obj.bounds {
113                                    if let TypeParamBound::Trait(bound_trait) = bound {
114                                        let bound_ident = get_path_ident(&bound_trait.path);
115                                        result.push_str("_dyn_");
116                                        result.push_str(&bound_ident.to_string());
117                                    }
118                                }
119                            } else {
120                                arg.span()
121                                    .unwrap()
122                                    .error(
123                                        "#[turbo_tasks::value_impl] does not support this type \
124                                         argument",
125                                    )
126                                    .emit();
127                            }
128                        }
129                        _ => arg
130                            .span()
131                            .unwrap()
132                            .error("#[turbo_tasks::value_impl] does not support this type argument")
133                            .emit(),
134                    }
135                }
136            }
137            PathArguments::None => {}
138            _ => {
139                segment
140                    .span()
141                    .unwrap()
142                    .error("#[turbo_tasks::value_impl] does not support this type argument")
143                    .emit();
144            }
145        }
146    }
147
148    Ident::new(&result, path.span())
149}
150
151pub fn get_type_ident(ty: &Type) -> Option<Ident> {
152    match ty {
153        Type::Path(path) => Some(get_path_ident(&path.path)),
154        Type::Tuple(tuple) => Some(Ident::new("unit", tuple.span())),
155        _ => {
156            ty.span()
157                .unwrap()
158                .error(format!(
159                    "#[turbo_tasks::value_impl] does not support the type {}, expected T or \
160                     Box<dyn Trait>",
161                    ty.to_token_stream()
162                ))
163                .emit();
164            None
165        }
166    }
167}
168pub fn get_trait_default_impl_function_ident(trait_ident: &Ident, ident: &Ident) -> Ident {
169    Ident::new(
170        &format!(
171            "{}_DEFAULT_IMPL_{}_FUNCTION",
172            trait_ident.to_string().to_uppercase(),
173            ident.to_string().to_uppercase()
174        ),
175        ident.span(),
176    )
177}
178
179pub fn get_value_type_ident(ident: &Ident) -> Ident {
180    Ident::new(
181        &format!("{}_VALUE_TYPE", ident.to_string().to_uppercase()),
182        ident.span(),
183    )
184}