summaryrefslogtreecommitdiff
path: root/engine-macros/src/util.rs
blob: 515b066912c8fed1de96287dbc4174084b5351c5 (plain)
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
54
55
56
57
58
59
60
61
62
63
64
65
use std::fmt::Write;

use quote::ToTokens;

macro_rules! syn_path {
    ($first_segment: ident $(::$segment: ident)*) => {
        ::syn::Path {
            leading_colon: None,
            segments: ::syn::punctuated::Punctuated::from_iter([
                syn_path_segment!($first_segment),
                $(syn_path_segment!($segment),)*
            ])
        }
    };
}

macro_rules! syn_path_segment {
    ($segment: ident) => {
        ::syn::PathSegment {
            ident: ::proc_macro2::Ident::new(
                stringify!($segment),
                ::proc_macro2::Span::call_site(),
            ),
            arguments: ::syn::PathArguments::None,
        }
    };
}

pub fn find_engine_crate_path() -> Option<syn::Path>
{
    let cargo_crate_name = std::env::var("CARGO_CRATE_NAME").ok()?;
    let cargo_pkg_name = std::env::var("CARGO_PKG_NAME").ok()?;

    if cargo_pkg_name == "engine" && cargo_crate_name != "engine" {
        // Macro is used by a crate example/test/benchmark
        return Some(syn_path!(engine));
    }

    if cargo_crate_name == "engine" {
        return Some(syn_path!(crate));
    }

    Some(syn_path!(engine))
}

pub fn syn_path_to_string(path: &syn::Path) -> String
{
    let mut output = String::with_capacity(2 + path.segments.len() * 8);

    if let Some(leading_colon) = path.leading_colon {
        write!(output, "{}", leading_colon.to_token_stream()).unwrap();
    }

    for (segment, punct) in path.segments.pairs().map(syn::punctuated::Pair::into_tuple) {
        let segment_ident = &segment.ident;

        write!(output, "{segment_ident}",).unwrap();

        if let Some(punct) = punct {
            write!(output, "{}", punct.to_token_stream()).unwrap();
        }
    }

    output
}