summaryrefslogtreecommitdiff
path: root/engine-macros/src/util.rs
diff options
context:
space:
mode:
Diffstat (limited to 'engine-macros/src/util.rs')
-rw-r--r--engine-macros/src/util.rs65
1 files changed, 65 insertions, 0 deletions
diff --git a/engine-macros/src/util.rs b/engine-macros/src/util.rs
new file mode 100644
index 0000000..515b066
--- /dev/null
+++ b/engine-macros/src/util.rs
@@ -0,0 +1,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
+}