Allow relative assets in rust > 1.88 (#4658)

* Allow relative assets in rust > 1.88 and assets outside of the crate in
binary crates

* undo changes to assets outside of the crate

* don't use relative assets in examples
This commit is contained in:
Evan Almloff authored and GitHub committed 2025-09-15 10:43:30 -07:00
1 parent 707bde2986
commit 5104644b34
10 files changed
+28 -14

No files matched your search

Generated
+4 -4
View File
@@ -12744,9 +12744,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068"
[[package]] [[package]]
name = "proc-macro2" name = "proc-macro2"
version = "1.0.95" version = "1.0.101"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de"
dependencies = [ dependencies = [
"unicode-ident", "unicode-ident",
] ]
@@ -13958,9 +13958,9 @@ dependencies = [
[[package]] [[package]]
name = "rustversion" name = "rustversion"
version = "1.0.21" version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d"
[[package]] [[package]]
name = "rustybuzz" name = "rustybuzz"
+1 -1
View File
@@ -276,7 +276,7 @@ serde_json = "1.0.140"
serde = "1.0.219" serde = "1.0.219"
syn = "2.0" syn = "2.0"
quote = "1.0" quote = "1.0"
proc-macro2 = "1.0" proc-macro2 = "1.0.101"
axum_session = "0.16.0" axum_session = "0.16.0"
axum_session_auth = "0.16.0" axum_session_auth = "0.16.0"
axum_session_sqlx = "0.5.0" axum_session_sqlx = "0.5.0"
+1 -1
View File
@@ -12,7 +12,7 @@ mod bevy_scene_plugin;
mod demo_renderer; mod demo_renderer;
// CSS Styles // CSS Styles
static STYLES: Asset = asset!("./src/styles.css"); static STYLES: Asset = asset!("/src/styles.css");
type Color = OpaqueColor<Srgb>; type Color = OpaqueColor<Srgb>;
+1 -1
View File
@@ -10,7 +10,7 @@ fn app() -> Element {
let mut animated_classes = use_signal(|| ["animated-text", ""]); let mut animated_classes = use_signal(|| ["animated-text", ""]);
rsx! { rsx! {
document::Link { rel: "stylesheet", href: asset!("./examples/assets/visible.css") } document::Link { rel: "stylesheet", href: asset!("/examples/assets/visible.css") }
div { div {
class: "container", class: "container",
+1 -1
View File
@@ -11,7 +11,7 @@ use winit::window::WindowAttributes;
mod demo_renderer; mod demo_renderer;
// CSS Styles // CSS Styles
static STYLES: Asset = asset!("./src/styles.css"); static STYLES: Asset = asset!("/src/styles.css");
// WGPU settings required by this example // WGPU settings required by this example
const FEATURES: Features = Features::PUSH_CONSTANTS; const FEATURES: Features = Features::PUSH_CONSTANTS;
+1 -1
View File
@@ -13,7 +13,7 @@ keywords = ["web", "desktop", "mobile", "gui", "wasm"]
proc-macro = true proc-macro = true
[dependencies] [dependencies]
proc-macro2 = { version = "1.0" } proc-macro2 = { workspace = true }
quote = { workspace = true } quote = { workspace = true }
[features] [features]
+1 -1
View File
@@ -15,7 +15,7 @@ proc-macro = true
# be careful with dependencies you add here - these need to get compiled for the proc macro and therefore # be careful with dependencies you add here - these need to get compiled for the proc macro and therefore
# prevent the main code from compiling! # prevent the main code from compiling!
[dependencies] [dependencies]
proc-macro2 = { workspace = true } proc-macro2 = { workspace = true, features = ["span-locations"] }
quote = { workspace = true } quote = { workspace = true }
syn = { workspace = true, features = ["full", "extra-traits"] } syn = { workspace = true, features = ["full", "extra-traits"] }
manganis-core = { workspace = true } manganis-core = { workspace = true }
@@ -45,7 +45,7 @@ impl Parse for AssetParser {
fn parse(input: ParseStream) -> syn::Result<Self> { fn parse(input: ParseStream) -> syn::Result<Self> {
// And then parse the options // And then parse the options
let (MacroString(src), path_expr) = input.call(crate::parse_with_tokens)?; let (MacroString(src), path_expr) = input.call(crate::parse_with_tokens)?;
let asset = resolve_path(&src); let asset = resolve_path(&src, path_expr.span());
let _comma = input.parse::<Token![,]>(); let _comma = input.parse::<Token![,]>();
let options = input.parse()?; let options = input.parse()?;
@@ -4,6 +4,7 @@ use proc_macro2::{Span, TokenStream};
use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use quote::{format_ident, quote, ToTokens, TokenStreamExt};
use syn::{ use syn::{
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
spanned::Spanned,
token::Comma, token::Comma,
Ident, Token, Visibility, Ident, Token, Visibility,
}; };
@@ -27,7 +28,7 @@ impl Parse for CssModuleParser {
// Asset path "/path.css" // Asset path "/path.css"
let (MacroString(src), path_expr) = input.call(crate::parse_with_tokens)?; let (MacroString(src), path_expr) = input.call(crate::parse_with_tokens)?;
let asset = resolve_path(&src); let asset = resolve_path(&src, path_expr.span());
let _comma = input.parse::<Comma>(); let _comma = input.parse::<Comma>();
+15 -2
View File
@@ -9,6 +9,7 @@ use std::{
use css_module::CssModuleParser; use css_module::CssModuleParser;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use proc_macro2::Span;
use quote::{quote, ToTokens}; use quote::{quote, ToTokens};
use syn::{ use syn::{
parse::{Parse, ParseStream}, parse::{Parse, ParseStream},
@@ -169,7 +170,7 @@ pub fn css_module(input: TokenStream) -> TokenStream {
quote! { #style }.into_token_stream().into() quote! { #style }.into_token_stream().into()
} }
fn resolve_path(raw: &str) -> Result<PathBuf, AssetParseError> { fn resolve_path(raw: &str, span: Span) -> Result<PathBuf, AssetParseError> {
// Get the location of the root of the crate which is where all assets are relative to // Get the location of the root of the crate which is where all assets are relative to
// //
// IE // IE
@@ -186,8 +187,18 @@ fn resolve_path(raw: &str) -> Result<PathBuf, AssetParseError> {
// 1. the input file should be a pathbuf // 1. the input file should be a pathbuf
let input = PathBuf::from(raw); let input = PathBuf::from(raw);
let path = if raw.starts_with('.') {
if let Some(local_folder) = span.local_file().as_ref().and_then(|f| f.parent()) {
local_folder.join(raw)
} else {
return Err(AssetParseError::RelativeAssetPath);
}
} else {
manifest_dir.join(raw.trim_start_matches('/'))
};
// 2. absolute path to the asset // 2. absolute path to the asset
let Ok(path) = std::path::absolute(manifest_dir.join(raw.trim_start_matches('/'))) else { let Ok(path) = std::path::absolute(path) else {
return Err(AssetParseError::InvalidPath { return Err(AssetParseError::InvalidPath {
path: input.clone(), path: input.clone(),
}); });
@@ -275,6 +286,7 @@ enum AssetParseError {
IoError { err: std::io::Error, path: PathBuf }, IoError { err: std::io::Error, path: PathBuf },
InvalidPath { path: PathBuf }, InvalidPath { path: PathBuf },
FailedToReadAsset(std::io::Error), FailedToReadAsset(std::io::Error),
RelativeAssetPath,
} }
impl std::fmt::Display for AssetParseError { impl std::fmt::Display for AssetParseError {
@@ -294,6 +306,7 @@ impl std::fmt::Display for AssetParseError {
) )
} }
AssetParseError::FailedToReadAsset(err) => write!(f, "Failed to read asset: {}", err), AssetParseError::FailedToReadAsset(err) => write!(f, "Failed to read asset: {}", err),
AssetParseError::RelativeAssetPath => write!(f, "Failed to resolve relative asset path. Relative assets are only supported in rust 1.88+."),
} }
} }
} }