diff --git a/Cargo.lock b/Cargo.lock index 0bfd3381f..85539b0ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -12744,9 +12744,9 @@ checksum = "dc375e1527247fe1a97d8b7156678dfe7c1af2fc075c9a4db3690ecd2a148068" [[package]] name = "proc-macro2" -version = "1.0.95" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02b3e5e68a3a1a02aad3ec490a98007cbc13c37cbe84a3cd7b8e406d76e7f778" +checksum = "89ae43fd86e4158d6db51ad8e2b80f313af9cc74f5c0e03ccb87de09998732de" dependencies = [ "unicode-ident", ] @@ -13958,9 +13958,9 @@ dependencies = [ [[package]] name = "rustversion" -version = "1.0.21" +version = "1.0.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d197bd2c9dc6e53b84da9556a69ba4cdfab8619eb41a8bd1cc2027a0f6b1d" +checksum = "b39cdef0fa800fc44525c84ccb54a029961a8215f9619753635a9c0d2538d46d" [[package]] name = "rustybuzz" diff --git a/Cargo.toml b/Cargo.toml index 76a14c0ad..fd6ff6b94 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -276,7 +276,7 @@ serde_json = "1.0.140" serde = "1.0.219" syn = "2.0" quote = "1.0" -proc-macro2 = "1.0" +proc-macro2 = "1.0.101" axum_session = "0.16.0" axum_session_auth = "0.16.0" axum_session_sqlx = "0.5.0" diff --git a/examples/bevy/src/main.rs b/examples/bevy/src/main.rs index 8a3f63dbe..41ac6458a 100644 --- a/examples/bevy/src/main.rs +++ b/examples/bevy/src/main.rs @@ -12,7 +12,7 @@ mod bevy_scene_plugin; mod demo_renderer; // CSS Styles -static STYLES: Asset = asset!("./src/styles.css"); +static STYLES: Asset = asset!("/src/styles.css"); type Color = OpaqueColor; diff --git a/examples/visible.rs b/examples/visible.rs index e8c1d7b61..9ed46b732 100644 --- a/examples/visible.rs +++ b/examples/visible.rs @@ -10,7 +10,7 @@ fn app() -> Element { let mut animated_classes = use_signal(|| ["animated-text", ""]); rsx! { - document::Link { rel: "stylesheet", href: asset!("./examples/assets/visible.css") } + document::Link { rel: "stylesheet", href: asset!("/examples/assets/visible.css") } div { class: "container", diff --git a/examples/wgpu-texture/src/main.rs b/examples/wgpu-texture/src/main.rs index dca441384..e46fc4385 100644 --- a/examples/wgpu-texture/src/main.rs +++ b/examples/wgpu-texture/src/main.rs @@ -11,7 +11,7 @@ use winit::window::WindowAttributes; mod demo_renderer; // CSS Styles -static STYLES: Asset = asset!("./src/styles.css"); +static STYLES: Asset = asset!("/src/styles.css"); // WGPU settings required by this example const FEATURES: Features = Features::PUSH_CONSTANTS; diff --git a/packages/config-macro/Cargo.toml b/packages/config-macro/Cargo.toml index d233fd90e..6cbb86024 100644 --- a/packages/config-macro/Cargo.toml +++ b/packages/config-macro/Cargo.toml @@ -13,7 +13,7 @@ keywords = ["web", "desktop", "mobile", "gui", "wasm"] proc-macro = true [dependencies] -proc-macro2 = { version = "1.0" } +proc-macro2 = { workspace = true } quote = { workspace = true } [features] diff --git a/packages/manganis/manganis-macro/Cargo.toml b/packages/manganis/manganis-macro/Cargo.toml index 46042ad6c..7371141b9 100644 --- a/packages/manganis/manganis-macro/Cargo.toml +++ b/packages/manganis/manganis-macro/Cargo.toml @@ -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 # prevent the main code from compiling! [dependencies] -proc-macro2 = { workspace = true } +proc-macro2 = { workspace = true, features = ["span-locations"] } quote = { workspace = true } syn = { workspace = true, features = ["full", "extra-traits"] } manganis-core = { workspace = true } diff --git a/packages/manganis/manganis-macro/src/asset.rs b/packages/manganis/manganis-macro/src/asset.rs index 83c217cd5..cfb07548d 100644 --- a/packages/manganis/manganis-macro/src/asset.rs +++ b/packages/manganis/manganis-macro/src/asset.rs @@ -45,7 +45,7 @@ impl Parse for AssetParser { fn parse(input: ParseStream) -> syn::Result { // And then parse the options 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::(); let options = input.parse()?; diff --git a/packages/manganis/manganis-macro/src/css_module.rs b/packages/manganis/manganis-macro/src/css_module.rs index b11a88499..6484811b0 100644 --- a/packages/manganis/manganis-macro/src/css_module.rs +++ b/packages/manganis/manganis-macro/src/css_module.rs @@ -4,6 +4,7 @@ use proc_macro2::{Span, TokenStream}; use quote::{format_ident, quote, ToTokens, TokenStreamExt}; use syn::{ parse::{Parse, ParseStream}, + spanned::Spanned, token::Comma, Ident, Token, Visibility, }; @@ -27,7 +28,7 @@ impl Parse for CssModuleParser { // Asset path "/path.css" 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::(); diff --git a/packages/manganis/manganis-macro/src/lib.rs b/packages/manganis/manganis-macro/src/lib.rs index e497d805b..47a18a92e 100644 --- a/packages/manganis/manganis-macro/src/lib.rs +++ b/packages/manganis/manganis-macro/src/lib.rs @@ -9,6 +9,7 @@ use std::{ use css_module::CssModuleParser; use proc_macro::TokenStream; +use proc_macro2::Span; use quote::{quote, ToTokens}; use syn::{ parse::{Parse, ParseStream}, @@ -169,7 +170,7 @@ pub fn css_module(input: TokenStream) -> TokenStream { quote! { #style }.into_token_stream().into() } -fn resolve_path(raw: &str) -> Result { +fn resolve_path(raw: &str, span: Span) -> Result { // Get the location of the root of the crate which is where all assets are relative to // // IE @@ -186,8 +187,18 @@ fn resolve_path(raw: &str) -> Result { // 1. the input file should be a pathbuf 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 - 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 { path: input.clone(), }); @@ -275,6 +286,7 @@ enum AssetParseError { IoError { err: std::io::Error, path: PathBuf }, InvalidPath { path: PathBuf }, FailedToReadAsset(std::io::Error), + RelativeAssetPath, } 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::RelativeAssetPath => write!(f, "Failed to resolve relative asset path. Relative assets are only supported in rust 1.88+."), } } }