1use syn::*;
2
3pub mod finalize;
4mod process_module;
5mod process_trait;
6
7pub use proc_macro_error;
8pub use type_leak;
9
10pub use process_module::process_module;
11pub use process_trait::process_trait;
12
13fn is_decycle_attribute(attr: &Attribute) -> bool {
14 let path = &attr.path();
15 path.is_ident("decycle")
16 || (path.segments.len() == 2
17 && (&path.segments[0].ident == "decycle"
18 || is_renamed_decycle_crate(&path.segments[0].ident))
19 && &path.segments[1].ident == "decycle")
20}
21
22fn is_renamed_decycle_crate(ident: &proc_macro2::Ident) -> bool {
23 let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").unwrap_or_default();
24
25 if let Ok(cargo_toml) = std::fs::read_to_string(format!("{}/Cargo.toml", manifest_dir)) {
26 if cargo_toml.contains(&format!("{} = {{ package = \"decycle\"", ident))
27 || cargo_toml.contains(&format!("{} = {{ package = 'decycle'", ident))
28 {
29 return true;
30 }
31 }
32
33 false
34}
35
36fn ident_to_path(ident: &Ident) -> Path {
37 Path {
38 leading_colon: None,
39 segments: core::iter::once(PathSegment {
40 ident: ident.clone(),
41 arguments: PathArguments::None,
42 })
43 .collect(),
44 }
45}
46
47fn get_random() -> u64 {
48 identity_to_u64(&get_crate_identity())
49}
50
51fn get_crate_identity() -> String {
52 "decycle".to_string()
53}
54
55fn identity_to_u64(value: &str) -> u64 {
56 const FNV_OFFSET: u64 = 0xcbf29ce484222325;
58 const FNV_PRIME: u64 = 0x100000001b3;
59 let mut hash = FNV_OFFSET;
60 for byte in value.as_bytes() {
61 hash ^= u64::from(*byte);
62 hash = hash.wrapping_mul(FNV_PRIME);
63 }
64 hash
65}