forked from bevyengine/bevy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
…engine#9956) # Objective - Fixes bevyengine#9363 ## Solution Moved `fq_std` from `bevy_reflect_derive` to `bevy_macro_utils`. This does make the `FQ*` types public where they were previously private, which is a change to the public-facing API, but I don't believe a breaking one. Additionally, I've done a basic QA pass over the `bevy_macro_utils` crate, adding `deny(unsafe)`, `warn(missing_docs)`, and documentation where required.
- Loading branch information
1 parent
25964bd
commit ee3001b
Showing
18 changed files
with
384 additions
and
337 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,3 +13,4 @@ toml_edit = "0.19" | |
syn = "2.0" | ||
quote = "1.0" | ||
rustc-hash = "1.0" | ||
proc-macro2 = "1.0" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
extern crate proc_macro; | ||
|
||
use proc_macro::TokenStream; | ||
use std::{env, path::PathBuf}; | ||
use toml_edit::{Document, Item}; | ||
|
||
/// The path to the `Cargo.toml` file for the Bevy project. | ||
pub struct BevyManifest { | ||
manifest: Document, | ||
} | ||
|
||
impl Default for BevyManifest { | ||
fn default() -> Self { | ||
Self { | ||
manifest: env::var_os("CARGO_MANIFEST_DIR") | ||
.map(PathBuf::from) | ||
.map(|mut path| { | ||
path.push("Cargo.toml"); | ||
if !path.exists() { | ||
panic!( | ||
"No Cargo manifest found for crate. Expected: {}", | ||
path.display() | ||
); | ||
} | ||
let manifest = std::fs::read_to_string(path.clone()).unwrap_or_else(|_| { | ||
panic!("Unable to read cargo manifest: {}", path.display()) | ||
}); | ||
manifest.parse::<Document>().unwrap_or_else(|_| { | ||
panic!("Failed to parse cargo manifest: {}", path.display()) | ||
}) | ||
}) | ||
.expect("CARGO_MANIFEST_DIR is not defined."), | ||
} | ||
} | ||
} | ||
const BEVY: &str = "bevy"; | ||
const BEVY_INTERNAL: &str = "bevy_internal"; | ||
|
||
impl BevyManifest { | ||
/// Attempt to retrieve the [path](syn::Path) of a particular package in | ||
/// the [manifest](BevyManifest) by [name](str). | ||
pub fn maybe_get_path(&self, name: &str) -> Option<syn::Path> { | ||
fn dep_package(dep: &Item) -> Option<&str> { | ||
if dep.as_str().is_some() { | ||
None | ||
} else { | ||
dep.get("package").map(|name| name.as_str().unwrap()) | ||
} | ||
} | ||
|
||
let find_in_deps = |deps: &Item| -> Option<syn::Path> { | ||
let package = if let Some(dep) = deps.get(name) { | ||
return Some(Self::parse_str(dep_package(dep).unwrap_or(name))); | ||
} else if let Some(dep) = deps.get(BEVY) { | ||
dep_package(dep).unwrap_or(BEVY) | ||
} else if let Some(dep) = deps.get(BEVY_INTERNAL) { | ||
dep_package(dep).unwrap_or(BEVY_INTERNAL) | ||
} else { | ||
return None; | ||
}; | ||
|
||
let mut path = Self::parse_str::<syn::Path>(package); | ||
if let Some(module) = name.strip_prefix("bevy_") { | ||
path.segments.push(Self::parse_str(module)); | ||
} | ||
Some(path) | ||
}; | ||
|
||
let deps = self.manifest.get("dependencies"); | ||
let deps_dev = self.manifest.get("dev-dependencies"); | ||
|
||
deps.and_then(find_in_deps) | ||
.or_else(|| deps_dev.and_then(find_in_deps)) | ||
} | ||
|
||
/// Returns the path for the crate with the given name. | ||
/// | ||
/// This is a convenience method for constructing a [manifest] and | ||
/// calling the [`get_path`] method. | ||
/// | ||
/// This method should only be used where you just need the path and can't | ||
/// cache the [manifest]. If caching is possible, it's recommended to create | ||
/// the [manifest] yourself and use the [`get_path`] method. | ||
/// | ||
/// [`get_path`]: Self::get_path | ||
/// [manifest]: Self | ||
pub fn get_path_direct(name: &str) -> syn::Path { | ||
Self::default().get_path(name) | ||
} | ||
|
||
/// Returns the path for the crate with the given name. | ||
pub fn get_path(&self, name: &str) -> syn::Path { | ||
self.maybe_get_path(name) | ||
.unwrap_or_else(|| Self::parse_str(name)) | ||
} | ||
|
||
/// Attempt to parse the provided [path](str) as a [syntax tree node](syn::parse::Parse) | ||
pub fn try_parse_str<T: syn::parse::Parse>(path: &str) -> Option<T> { | ||
syn::parse(path.parse::<TokenStream>().ok()?).ok() | ||
} | ||
|
||
/// Attempt to parse provided [path](str) as a [syntax tree node](syn::parse::Parse). | ||
/// | ||
/// # Panics | ||
/// | ||
/// Will panic if the path is not able to be parsed. For a non-panicing option, see [`try_parse_str`] | ||
/// | ||
/// [`try_parse_str`]: Self::try_parse_str | ||
pub fn parse_str<T: syn::parse::Parse>(path: &str) -> T { | ||
Self::try_parse_str(path).unwrap() | ||
} | ||
|
||
/// Attempt to get a subcrate [path](syn::Path) under Bevy by [name](str) | ||
pub fn get_subcrate(&self, subcrate: &str) -> Option<syn::Path> { | ||
self.maybe_get_path(BEVY) | ||
.map(|bevy_path| { | ||
let mut segments = bevy_path.segments; | ||
segments.push(BevyManifest::parse_str(subcrate)); | ||
syn::Path { | ||
leading_colon: None, | ||
segments, | ||
} | ||
}) | ||
.or_else(|| self.maybe_get_path(&format!("bevy_{subcrate}"))) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.