diff --git a/.github/workflows/cbt.yml b/.github/workflows/cbt.yml
index b8773f0..23416dd 100644
--- a/.github/workflows/cbt.yml
+++ b/.github/workflows/cbt.yml
@@ -1,26 +1,41 @@
name: cargo basic build-test
on:
- push:
- branches: ["window", "master"]
- pull_request:
- branches: ["window"]
+ push:
+ branches: ["window", "master"]
+ pull_request:
+ branches: ["window"]
env:
- CARGO_TERM_COLOR: always
+ CARGO_TERM_COLOR: always
jobs:
- build_and_test:
- name: Sabry - latest
- runs-on: ubuntu-latest
- strategy:
- matrix:
- toolchain:
- - stable
- - nightly
- steps:
- - uses: actions/checkout@v4
- - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
- - run: cargo build --verbose
- - run: cargo test --verbose --all
- - run: cargo test --verbose --all --all-features
+ build_and_test:
+ name: Sabry - latest
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ toolchain:
+ - stable
+ - nightly
+ steps:
+ - uses: actions/checkout@v4
+ - run: rustup update ${{ matrix.toolchain }} && rustup default ${{ matrix.toolchain }}
+ - run: cargo build --verbose
+ - run: cargo test --verbose --all
+ - run: cargo test --verbose --all --all-features
+
+ build_examples:
+ name: Sabry - latset - examples
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ example:
+ - define-styles
+ - use-styles
+ - leptos-axum
+ steps:
+ - uses: actions/checkout@v4
+ - run: rustup update nightly && rustup default nightly
+ - run: cd examples/${{ matrix.example }}
+ - run: cargo build --verbose
diff --git a/Cargo.toml b/Cargo.toml
index 5c90aae..38499c1 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -59,6 +59,9 @@ build = [
net-files = [
"sabry_build/net-files"
]
+nightly = [
+ "sabry_procmacro?/nightly"
+]
internals = []
[package.metadata.docs.rs]
diff --git a/README.md b/README.md
index ae87410..afb8f1d 100644
--- a/README.md
+++ b/README.md
@@ -130,8 +130,8 @@ Also, just about everything is pub-available in this crate (with *internals* fea
Feel free to check out examples:
-|[crate of styles](https://github.com/yiffyrusdev/sabry/tree/master/examples/define-styles)|[style usage](https://github.com/yiffyrusdev/sabry/tree/master/examples/use-styles)|[leptos-axum with sabry](https://github.com/yiffyrusdev/sabry/tree/master/examples/leptos-axum)|
-|-|-|-|
+|[crate of styles](https://github.com/yiffyrusdev/sabry/tree/master/examples/define-styles)|[style usage](https://github.com/yiffyrusdev/sabry/tree/master/examples/use-styles)|[leptos-axum with sabry](https://github.com/yiffyrusdev/sabry/tree/master/examples/leptos-axum)|[leptos components](https://github.com/yiffyrusdev/sabry/tree/master/examples/leptos-components)|
+|-|-|-|-|
### Create a crate full of arbitrary SASS
@@ -256,6 +256,23 @@ styly!(styles {"
```
So the `mixins!` macro we just passed to the `usey!` macro inside of `buildy` function call is now accessible with simple and natural `@use "mixins"` SASS rule!
+### Create crate of styled components
+
+This is currently an alpha-testing-early-concept feature which comes
+with some things to avoid.
+
+While the process depends much on the framework you prefer, there are
+some limitations and essential recommendations:
+
+- Sabry will scope (hash) your styles at build time, which means
+higher collision probability between the component crate and the main application, which *can not* be currently
+detected by sabry.
+- You have to write style scopes for components with `const` styly macro flavour: `styly!(const whatever {""})`
+ - And then you have to solve the task of injecting those generated CSS for your component manually.
+- If you want to write styles in separate SASS/SCSS files, you need the nightly rust and the 'nightly' feature flag set
+for sabry, so you can use styles from relative paths `styly!(const comp "./style.scss")`
+ - Which will give you an error from rust-analyzer wether file exists or not. However, if the path is correct, it will build fine.
+
### Leptos specials
With [leptos](https://github.com/leptos-rs/leptos) framework you can do the trick to apply some class to most of HtmlElements for the entire component/island:
@@ -461,6 +478,8 @@ The given code to `scssy!` is not checked to be valid code in given syntax (wip)
> SASS support inside of rust files is experimental. If you do want to use SASS tabbed syntax - consider to use files path instead of sass-in-rust option.
+> With *nightly* feature flag if using the relative path like `scssy!(module "./module.scss")` you'll get false-positive error even if file exists. Also you won't get autocompletion and rust-analyzer will complain on `module!` macro. WIP.
+
### Scoping with `styly!`
The `styly!` macro is available with *procmacro* feature flag which is enabled by default.
@@ -541,6 +560,8 @@ mod scope {/* selector collection */}
>
> Worth of notice: sabry will still include const-flavored styles into the CSS bundle during build time.
+> With *nightly* feature flag if using the relative path like `styly!(const scope "./sctyle.scss")` you'll get false-positive error even if file exists. Also you won't get autocompletion and rust-analyzer will complain on `SCOPE_CSS`, `scope::whatever` etc. WIP.
+
### Building with `buildy` and `usey!`
The `buildy` function is available with *build* feature which needs to be enabled explicitly.
@@ -658,6 +679,8 @@ Not any valid CSS selector is a valid rust identifier. In general this section s
**lepty-scoping** - overhauls the scope generation logic, best suitable for the leptos. Check out the [section](#leptos-specials) and an [example](https://github.com/yiffyrusdev/sabry/tree/master/examples/leptos-axum)
+**nightly** - allows relative path selection with `scssy!` and `styly!` macros. However rust-analyzer will raise false-positives for reachable files as well.
+
## WIP
*(sorted by my own priority)*, "dones" are excluded
@@ -666,6 +689,8 @@ Not any valid CSS selector is a valid rust identifier. In general this section s
- [ ] some weird unrelated stuff I can see in autocompletion
- [ ] Crates of styled components - currently the only way to create them seems to be const styly.
- [ ] CSS support
+ - [x] Allow relative path selection (with 'nightly' feature on nightly rust)
+ - [ ] Somehow get rid of false-positives AND retain proper autocompletion
- [ ] Currently the crate causes "dependency inheritance" infection. We cant get rid of it, however should be doable to at least get rid of flag inheritance
- [ ] Use sass-in-rust without quoted styles for variable injection:
```rust, ignore
diff --git a/examples/define-styles/Cargo.lock b/examples/define-styles/Cargo.lock
index 73cad63..87b2f50 100644
--- a/examples/define-styles/Cargo.lock
+++ b/examples/define-styles/Cargo.lock
@@ -974,7 +974,7 @@ checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f"
[[package]]
name = "sabry"
-version = "0.0.1-beta.2"
+version = "0.0.1"
dependencies = [
"sabry_intrnl",
"sabry_procmacro",
@@ -982,7 +982,7 @@ dependencies = [
[[package]]
name = "sabry_intrnl"
-version = "0.0.1-beta.2"
+version = "0.0.1"
dependencies = [
"base64",
"blake3",
@@ -1001,14 +1001,15 @@ dependencies = [
[[package]]
name = "sabry_procmacro"
-version = "0.0.1-beta.2"
+version = "0.0.1"
dependencies = [
+ "cfg-if",
"sabry_procmacro_impl",
]
[[package]]
name = "sabry_procmacro_impl"
-version = "0.0.1-beta.2"
+version = "0.0.1"
dependencies = [
"proc-macro2",
"quote",
diff --git a/examples/define-styles/Cargo.toml b/examples/define-styles/Cargo.toml
index 4e80fbe..4288abb 100644
--- a/examples/define-styles/Cargo.toml
+++ b/examples/define-styles/Cargo.toml
@@ -6,4 +6,4 @@ rust-version = "1.82"
publish = false
[dependencies]
-sabry = {path = "../../"}
+sabry = {path = "../../", features = ["nightly"]}
diff --git a/examples/define-styles/src/lib.rs b/examples/define-styles/src/lib.rs
index 0640d6e..7b1b5ee 100644
--- a/examples/define-styles/src/lib.rs
+++ b/examples/define-styles/src/lib.rs
@@ -1,6 +1,8 @@
use sabry::scssy;
-scssy!(style "src/style.scss");
+// relative path is available because 'nightly' feature flag is set.
+// If you don't - this will be "src/style.scss"
+scssy!(style "./style.scss");
scssy!(utils {"
@mixin flex($direction, $align, $justify, $gap: .5rem) {
diff --git a/examples/leptos-axum/Cargo.toml b/examples/leptos-axum/Cargo.toml
index 848c699..6fe0d77 100644
--- a/examples/leptos-axum/Cargo.toml
+++ b/examples/leptos-axum/Cargo.toml
@@ -9,16 +9,16 @@ publish = false
crate-type = ["cdylib", "rlib"]
[dependencies]
-leptos = { version = "0.7.0-gamma3" }
-leptos_axum = { version = "0.7.0-gamma3", optional = true }
-leptos_meta = { version = "0.7.0-gamma3" }
-leptos_router = { version = "0.7.0-gamma3" }
+leptos = { version = "0.7.0-rc1" }
+leptos_axum = { version = "0.7.0-rc1", optional = true }
+leptos_meta = { version = "0.7.0-rc1" }
+leptos_router = { version = "0.7.0-rc1" }
axum = { version = "0.7", optional = true }
console_error_panic_hook = "0.1"
tokio = { version = "1", features = ["rt-multi-thread"], optional = true }
tower = { version = "0.4", optional = true }
tower-http = { version = "0.5", features = ["fs"], optional = true }
-wasm-bindgen = "=0.2.93"
+wasm-bindgen = "=0.2.95"
thiserror = "1"
tracing = { version = "0.1", optional = true }
http = "1"
@@ -26,6 +26,9 @@ http = "1"
# sabry with sass
sabry = {path = "../../", features = ["lepty-scoping"]}
+# our component library
+leptos-components = {path = "../leptos-components"}
+
[build-dependencies]
# sabry for build with sass
sabry = {path = "../../", features = ["build", "lepty-scoping"]}
diff --git a/examples/leptos-axum/src/main.rs b/examples/leptos-axum/src/main.rs
index 355d992..d4b5b24 100644
--- a/examples/leptos-axum/src/main.rs
+++ b/examples/leptos-axum/src/main.rs
@@ -4,6 +4,7 @@
async fn main() {
use axum::Router;
use leptos::prelude::*;
+ use leptos::logging::*;
use leptos_axum::{generate_route_list, LeptosRoutes};
use leptos_axum_sabry::shell::*;
diff --git a/examples/leptos-axum/src/routes/home.rs b/examples/leptos-axum/src/routes/home.rs
index c8b8d4b..6d5e942 100644
--- a/examples/leptos-axum/src/routes/home.rs
+++ b/examples/leptos-axum/src/routes/home.rs
@@ -45,6 +45,7 @@ pub fn Route() -> impl IntoView {
let on_click = move |_| *count.write() += 1;
view! {class = STYLE,
+ // lets use our component
"Welcome to Leptos"
diff --git a/examples/leptos-axum/src/shell.rs b/examples/leptos-axum/src/shell.rs
index 125c90d..d1d757e 100644
--- a/examples/leptos-axum/src/shell.rs
+++ b/examples/leptos-axum/src/shell.rs
@@ -4,6 +4,7 @@ use leptos_router::{
components::{Route, Router, Routes},
StaticSegment,
};
+use sabry::styly;
use crate::routes;
@@ -29,7 +30,7 @@ pub fn shell(options: LeptosOptions) -> impl IntoView {
pub fn App() -> impl IntoView {
provide_meta_context();
- view! {
+ view! {class=APP,
@@ -41,3 +42,11 @@ pub fn App() -> impl IntoView {
}
}
+
+styly!(app:scss {"
+ @use 'theme';
+
+ main {
+ @include theme.surface(primary);
+ }
+"});
diff --git a/examples/leptos-components/.gitignore b/examples/leptos-components/.gitignore
new file mode 100644
index 0000000..6985cf1
--- /dev/null
+++ b/examples/leptos-components/.gitignore
@@ -0,0 +1,14 @@
+# Generated by Cargo
+# will have compiled files and executables
+debug/
+target/
+
+# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
+# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
+Cargo.lock
+
+# These are backup files generated by rustfmt
+**/*.rs.bk
+
+# MSVC Windows builds of rustc generate these, which store debugging information
+*.pdb
diff --git a/examples/leptos-components/Cargo.toml b/examples/leptos-components/Cargo.toml
new file mode 100644
index 0000000..2359885
--- /dev/null
+++ b/examples/leptos-components/Cargo.toml
@@ -0,0 +1,33 @@
+[package]
+name = "leptos-components"
+version = "0.1.0"
+rust-version = "1.82"
+edition = "2021"
+publish = false
+
+[lib]
+crate-type = ["cdylib", "rlib"]
+
+[dependencies]
+leptos = { version = "0.7.0-rc1" }
+leptos_meta = { version = "0.7.0-rc1" }
+leptos_router = { version = "0.7.0-rc1" }
+
+sabry = {path = "../../", features = ["lepty-scoping"]}
+
+[build-dependencies]
+sabry = {path = "../../", features = ["build", "lepty-scoping"]}
+define-styles = {path = "../define-styles"}
+
+[features]
+hydrate = ["leptos/hydrate"]
+ssr = [
+ "leptos/ssr",
+ "leptos_meta/ssr",
+ "leptos_router/ssr",
+]
+
+[package.metadata.sabry]
+css.minify = true
+# No need for bundle
+# css.bundle = "target/.sabry/target/bundle.css"
diff --git a/examples/leptos-components/LICENSE b/examples/leptos-components/LICENSE
new file mode 100644
index 0000000..fdddb29
--- /dev/null
+++ b/examples/leptos-components/LICENSE
@@ -0,0 +1,24 @@
+This is free and unencumbered software released into the public domain.
+
+Anyone is free to copy, modify, publish, use, compile, sell, or
+distribute this software, either in source code form or as a compiled
+binary, for any purpose, commercial or non-commercial, and by any
+means.
+
+In jurisdictions that recognize copyright laws, the author or authors
+of this software dedicate any and all copyright interest in the
+software to the public domain. We make this dedication for the benefit
+of the public at large and to the detriment of our heirs and
+successors. We intend this dedication to be an overt act of
+relinquishment in perpetuity of all present and future rights to this
+software under copyright law.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+
+For more information, please refer to
diff --git a/examples/leptos-components/README.md b/examples/leptos-components/README.md
new file mode 100644
index 0000000..bbfcf13
--- /dev/null
+++ b/examples/leptos-components/README.md
@@ -0,0 +1,6 @@
+
+
+
+
+
+This is an example of sabry with leptos-axum, made with [leptos-axum sterter template](https://github.com/leptos-rs/start-axum)
diff --git a/examples/leptos-components/build.rs b/examples/leptos-components/build.rs
new file mode 100644
index 0000000..be74188
--- /dev/null
+++ b/examples/leptos-components/build.rs
@@ -0,0 +1,11 @@
+use define_styles::{theme, utils, tokens};
+
+fn main(){
+ sabry::buildy(
+ sabry::usey!(
+ utils!(),
+ theme!(),
+ tokens!()
+ )
+ ).expect("Failed to build with sabry");
+}
diff --git a/examples/leptos-components/src/lib.rs b/examples/leptos-components/src/lib.rs
new file mode 100644
index 0000000..33a2aaf
--- /dev/null
+++ b/examples/leptos-components/src/lib.rs
@@ -0,0 +1,52 @@
+use leptos::prelude::*;
+use leptos_meta::Style;
+use sabry::styly;
+
+#[component]
+pub fn Aside() -> impl IntoView {
+ let showme = RwSignal::new(true);
+
+ view!{class=SCOPE,
+
+
+
+
+ }
+}
+
+styly!(const scope:scss {"
+ @use 'theme';
+ @use 'utils';
+ @use 'tokens';
+
+ aside {
+ @include theme.surface(secondary);
+ @include utils.flex(column, center, center);
+
+ position: fixed;
+ top: 0;
+ left: 0;
+ bottom: 0;
+ width: max-content;
+ z-index: 1000;
+ }
+
+ p {
+ @include theme.txt(primary);
+ font-size: 1rem;
+ }
+
+ .btn {
+ @include theme.surface(accent);
+ @include tokens.clickable();
+ }
+"});
diff --git a/examples/use-styles/Cargo.lock b/examples/use-styles/Cargo.lock
index 0807c2c..2ab59b6 100644
--- a/examples/use-styles/Cargo.lock
+++ b/examples/use-styles/Cargo.lock
@@ -1016,6 +1016,7 @@ dependencies = [
name = "sabry_procmacro"
version = "0.0.1"
dependencies = [
+ "cfg-if",
"sabry_procmacro_impl",
]
diff --git a/examples/use-styles/Cargo.toml b/examples/use-styles/Cargo.toml
index 29e0a32..c6241e0 100644
--- a/examples/use-styles/Cargo.toml
+++ b/examples/use-styles/Cargo.toml
@@ -6,10 +6,10 @@ rust-version = "1.82"
publish = false
[dependencies]
-sabry = {path = "../../"}
+sabry = {path = "../../", features = ["nightly"]}
[build-dependencies]
-sabry = {path = "../../", features = ["build"]}
+sabry = {path = "../../", features = ["build", "nightly"]}
define-styles = {path = "../define-styles"}
[package.metadata.sabry]
diff --git a/examples/use-styles/build.rs b/examples/use-styles/build.rs
index ec066dc..904431c 100644
--- a/examples/use-styles/build.rs
+++ b/examples/use-styles/build.rs
@@ -9,14 +9,8 @@ scssy!(utils {"
}
"});
-fn main(){
+fn main() {
/* Declare modules to use with sabry */
- sabry::buildy(
- usey!(
- theme!(),
- tokens!(),
- utils_dup!(),
- utils!()
- )
- ).expect("Failed to build sabry styles");
+ sabry::buildy(usey!(theme!(), tokens!(), utils_dup!(), utils!()))
+ .expect("Failed to build sabry styles");
}
diff --git a/examples/use-styles/src/main.rs b/examples/use-styles/src/main.rs
index 269cd12..f9cf8ac 100644
--- a/examples/use-styles/src/main.rs
+++ b/examples/use-styles/src/main.rs
@@ -17,7 +17,9 @@ styly!(pub const bundlemod {"
}
"});
-styly!(pub filemod:sass "src/main.sass");
+// relative path is available because 'nightly' feature flag is set.
+// If you don't - this will be "src/main.sass"
+styly!(pub const filemod:sass "./main.sass");
fn main() {
println!("someth class codemod styles: {}", bundlemod::someth);
@@ -28,5 +30,6 @@ fn main() {
);
println!("#fox id will be: {}", bundlemod::thefox);
println!("Bundles const CSS will be: {}", BUNDLEMOD_CSS);
+ println!("Bundles const CSS from file will be: {}", FILEMOD_CSS); // false-positive from relative file.
println!("Thats how we used the styles! Good luck!!");
}
diff --git a/sabry_build/src/filevisit.rs b/sabry_build/src/filevisit.rs
index 2844469..8574a4b 100644
--- a/sabry_build/src/filevisit.rs
+++ b/sabry_build/src/filevisit.rs
@@ -1,4 +1,7 @@
-use std::{fs, io, path::Path};
+use std::{
+ fs, io,
+ path::{Path, PathBuf},
+};
use proc_macro2::TokenStream;
use sabry_procmacro_impl::impls::styly;
@@ -6,7 +9,7 @@ use syn::{spanned::Spanned, visit::Visit};
#[derive(Debug, thiserror::Error)]
pub enum FileVisitError {
- #[error("Could not read file")]
+ #[error("tt read file")]
Read(#[from] io::Error),
#[error("styly! macro found, yet invalid")]
Styly(#[from] syn::Error),
@@ -19,6 +22,7 @@ pub fn visit_file(path: &Path) -> Result {
let mut styly_visitor = StylyVisitor {
found_stylys: vec![],
+ path: path.to_owned(),
};
styly_visitor.visit_file(&code_file);
@@ -34,17 +38,26 @@ pub fn visit_file(path: &Path) -> Result {
#[derive(Debug)]
pub struct StylyVisitor {
pub found_stylys: Vec,
+ pub path: PathBuf,
}
impl<'ast> Visit<'ast> for StylyVisitor {
fn visit_item_macro(&mut self, node: &'ast syn::ItemMacro) {
if node.mac.path.get_ident().is_some_and(|i| i == "styly") {
- let body = node.mac.parse_body::().unwrap_or_else(|_| {
- panic!("could not parse `styly!` macro at {:?}", node.mac.span())
- });
- let macro_data = styly::parse_macro_syntax(body).unwrap_or_else(|_| {
- panic!("could not parse `styly!` macro at {:?}", node.mac.span())
+ let body = node.mac.parse_body::().unwrap_or_else(|e| {
+ panic!(
+ "could not parse `styly!` macro at {:?}: {e:?}",
+ node.mac.span()
+ )
});
+ let macro_data =
+ styly::parse_macro_syntax(body, self.path.parent().map(|p| p.to_owned()))
+ .unwrap_or_else(|e| {
+ panic!(
+ "could not parse `styly!` macro at {:?}: {e:?}",
+ node.mac.span()
+ )
+ });
self.found_stylys.push(macro_data);
}
}
diff --git a/sabry_procmacro/Cargo.toml b/sabry_procmacro/Cargo.toml
index 570fccf..cb2c1bd 100644
--- a/sabry_procmacro/Cargo.toml
+++ b/sabry_procmacro/Cargo.toml
@@ -13,8 +13,10 @@ proc-macro = true
[dependencies]
sabry_procmacro_impl = {workspace = true}
+cfg-if = {version = "^1.0"}
[features]
+nightly = []
[package.metadata.docs.rs]
all-features = true
diff --git a/sabry_procmacro/src/lib.rs b/sabry_procmacro/src/lib.rs
index aed8a2c..5c9ffba 100644
--- a/sabry_procmacro/src/lib.rs
+++ b/sabry_procmacro/src/lib.rs
@@ -1,6 +1,8 @@
#![doc = include_str!("../README.md")]
+#![cfg_attr(feature = "nightly", feature(proc_macro_span))]
-use proc_macro::TokenStream;
+use cfg_if::cfg_if;
+use proc_macro::{Span, TokenStream};
use sabry_procmacro_impl::impls::{
scssy::scssy_macro_impl, styly::styly_macro_impl, usey::usey_macro_impl,
};
@@ -34,7 +36,14 @@ use sabry_procmacro_impl::impls::{
///
#[proc_macro]
pub fn scssy(input: TokenStream) -> TokenStream {
- scssy_macro_impl(input.into()).into()
+ cfg_if! {
+ if #[cfg(feature = "nightly")] {
+ let source_path = Span::call_site().source_file().path().parent().map(|p| p.to_owned());
+ } else {
+ let source_path = None;
+ }
+ }
+ scssy_macro_impl(input.into(), source_path).into()
}
/// Macro that brings sass code into app
@@ -96,7 +105,15 @@ pub fn scssy(input: TokenStream) -> TokenStream {
/// ```
#[proc_macro]
pub fn styly(input: TokenStream) -> TokenStream {
- styly_macro_impl(input.into()).into()
+ cfg_if! {
+ if #[cfg(feature = "nightly")] {
+ let source_path = Span::call_site().source_file().path().parent().map(|p| p.to_owned());
+ } else {
+ let source_path = None;
+ }
+ }
+
+ styly_macro_impl(input.into(), source_path).into()
}
/// Macro that brings external sass code into app
diff --git a/sabry_procmacro_impl/Cargo.toml b/sabry_procmacro_impl/Cargo.toml
index a7a1927..522fa2f 100644
--- a/sabry_procmacro_impl/Cargo.toml
+++ b/sabry_procmacro_impl/Cargo.toml
@@ -18,6 +18,7 @@ raffia = {version = "^0.9"}
regex = {version = "^1.11"}
[features]
+nightly = []
[package.metadata.docs.rs]
all-features = true
diff --git a/sabry_procmacro_impl/src/impls/mod.rs b/sabry_procmacro_impl/src/impls/mod.rs
index 47a6939..c82f67f 100644
--- a/sabry_procmacro_impl/src/impls/mod.rs
+++ b/sabry_procmacro_impl/src/impls/mod.rs
@@ -30,28 +30,29 @@ impl ArbitraryStyleBlock {
pub fn code(&self) -> &str {
&self.code
}
-}
-impl Parse for ArbitraryStyleBlock {
- fn parse(input: syn::parse::ParseStream) -> syn::Result {
+ pub fn parse_syn(
+ input: syn::parse::ParseStream,
+ use_code_path_prefix: Option,
+ ) -> syn::Result {
let (code, span) = if let Ok(path_tok) = input.parse::() {
- let path = path_tok.value();
-
- let path = match PathBuf::from_str(&path) {
- Ok(p) => p,
- Err(_) => {
- return Err(syn::Error::new(
- path_tok.span(),
- format!("Could not read {} as a path: Infallible", path),
- ))
+ let path = if let Some(prefix) = use_code_path_prefix {
+ let p = path_tok.value();
+ if let Some(pp) = p.strip_prefix("./") {
+ prefix.join(pp)
+ } else {
+ PathBuf::from_str(&p).expect("Unable to convert path into PathBuf")
}
+ } else {
+ PathBuf::from_str(&path_tok.value()).expect("Unable to convert path into PathBuf")
};
+
let fullpath = match path.canonicalize() {
Ok(cp) => cp,
Err(e) => {
return Err(syn::Error::new(
path_tok.span(),
- format!("Could not use path {path:?}: {:?}", e.kind()),
+ format!("Could not use path {path:?}: {:?}. If the path is relative and 'nightly' feature flag is set - this is likely false-positive", e.kind()),
))
}
};
@@ -86,6 +87,12 @@ impl Parse for ArbitraryStyleBlock {
}
}
+impl Parse for ArbitraryStyleBlock {
+ fn parse(input: syn::parse::ParseStream) -> syn::Result {
+ Self::parse_syn(input, None)
+ }
+}
+
#[allow(clippy::to_string_trait_impl)]
impl ToString for ArbitraryStyleBlock {
fn to_string(&self) -> String {
diff --git a/sabry_procmacro_impl/src/impls/scssy.rs b/sabry_procmacro_impl/src/impls/scssy.rs
index b82718d..0684b70 100644
--- a/sabry_procmacro_impl/src/impls/scssy.rs
+++ b/sabry_procmacro_impl/src/impls/scssy.rs
@@ -1,7 +1,12 @@
+use std::path::PathBuf;
+
use proc_macro2::TokenStream;
use quote::quote;
use sabry_intrnl::scoper::ArbitraryScope;
-use syn::{parse::Parse, Ident};
+use syn::{
+ parse::{Parse, ParseStream},
+ Ident,
+};
use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
@@ -11,31 +16,34 @@ use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
/// `$syntax`: sass/scss
///
/// `$code`: intended to be valid based on $syntax
-pub fn scssy_macro_impl(input: TokenStream) -> TokenStream {
+pub fn scssy_macro_impl(input: TokenStream, source_path: Option) -> TokenStream {
let MacroSyntax {
ident,
- syntax: mode,
+ syntax,
code,
- } = match syn::parse2::(input) {
+ } = match syn::parse::Parser::parse2(
+ |input: ParseStream<'_>| MacroSyntax::parse_syn(input, source_path),
+ input,
+ ) {
Ok(m) => m,
Err(e) => return e.to_compile_error(),
};
// quick raffia syntax check
- match ArbitraryScope::from_source(mode.0, ident.clone(), &code.code) {
+ match ArbitraryScope::from_source(syntax.0, ident.clone(), &code.code) {
Ok(_) => {}
Err(e) => return syn::Error::new(code.span, format!("{e:?}")).into_compile_error(),
}
let sourcesass = code.to_string();
- let macro_doc = format!("Arbitrary {:?} code declared with `scssy!`. Pretty usable in tandem with `usey!` and `magic()` at build time", mode);
+ let macro_doc = format!("Arbitrary {:?} code declared with `scssy!`. Pretty usable in tandem with `usey!` and `buildy` at build time", syntax);
quote! {
#[doc = #macro_doc]
#[macro_export]
macro_rules! #ident {
() => {#sourcesass};
- (syntax) => {#mode};
+ (syntax) => {#syntax};
}
}
}
@@ -46,19 +54,32 @@ pub struct MacroSyntax {
code: ArbitraryStyleBlock,
}
-impl Parse for MacroSyntax {
- fn parse(input: syn::parse::ParseStream) -> syn::Result {
+impl MacroSyntax {
+ pub fn parse_syn(
+ input: syn::parse::ParseStream,
+ source_path: Option,
+ ) -> syn::Result {
let ident = input.parse::()?;
- let mode = input.parse::()?;
- let code = input.parse::()?;
+ let syntax = input.parse::()?;
+
+ let code = match source_path {
+ Some(sp) => ArbitraryStyleBlock::parse_syn(input, Some(sp))?,
+ None => input.parse::()?,
+ };
Ok(Self {
ident,
- syntax: mode,
+ syntax,
code,
})
}
}
+impl Parse for MacroSyntax {
+ fn parse(input: syn::parse::ParseStream) -> syn::Result {
+ Self::parse_syn(input, None)
+ }
+}
+
#[cfg(test)]
mod test {}
diff --git a/sabry_procmacro_impl/src/impls/styly.rs b/sabry_procmacro_impl/src/impls/styly.rs
index 8d6ae1d..8231201 100644
--- a/sabry_procmacro_impl/src/impls/styly.rs
+++ b/sabry_procmacro_impl/src/impls/styly.rs
@@ -1,3 +1,5 @@
+use std::path::PathBuf;
+
use proc_macro2::{Span, TokenStream};
use quote::quote;
use sabry_intrnl::{
@@ -5,7 +7,10 @@ use sabry_intrnl::{
config::SabryConfig,
scoper::{apply_basic_rusty_member_gen_rules, ArbitraryScope, ScopedSelector},
};
-use syn::{parse::Parse, Ident, Token};
+use syn::{
+ parse::{Parse, ParseStream},
+ Ident, Token,
+};
use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
@@ -26,7 +31,7 @@ use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
///
/// The machine-readable output may also be forced by use `machine_readable: true` arg on `parse_macro_syntax` function
/// without modifying tokenstream
-pub fn styly_macro_impl(input: TokenStream) -> TokenStream {
+pub fn styly_macro_impl(input: TokenStream, source_path: Option) -> TokenStream {
let config = match SabryConfig::require() {
Ok(c) => c,
Err(e) => {
@@ -40,7 +45,7 @@ pub fn styly_macro_impl(input: TokenStream) -> TokenStream {
.to_compile_error()
}
};
- let ms = match parse_macro_syntax(input) {
+ let ms = match parse_macro_syntax(input, source_path) {
Ok(ms) => ms,
Err(e) => return e.to_compile_error(),
};
@@ -180,8 +185,14 @@ pub fn styly_macro_impl(input: TokenStream) -> TokenStream {
}
// reusable function, that does not return tokenstream for machine-processing at build time
-pub fn parse_macro_syntax(input: TokenStream) -> Result {
- syn::parse2::(input)
+pub fn parse_macro_syntax(
+ input: TokenStream,
+ source_path: Option,
+) -> Result {
+ syn::parse::Parser::parse2(
+ |input: ParseStream<'_>| MacroSyntax::parse_syn(input, source_path),
+ input,
+ )
}
#[derive(Debug)]
@@ -215,12 +226,19 @@ pub struct MacroSyntax {
pub code: ArbitraryStyleBlock,
}
-impl Parse for MacroSyntax {
- fn parse(input: syn::parse::ParseStream) -> syn::Result {
+impl MacroSyntax {
+ pub fn parse_syn(
+ input: syn::parse::ParseStream,
+ source_path: Option,
+ ) -> syn::Result {
let mut generator = input.parse::()?;
let scope = input.parse::()?;
let syntax = input.parse::()?;
- let code = input.parse::()?;
+ let code = if source_path.is_some() {
+ ArbitraryStyleBlock::parse_syn(input, source_path)
+ } else {
+ input.parse::()
+ }?;
if input.parse::().is_ok() {
generator = ScopeGenerator::MachineReadable
@@ -234,3 +252,9 @@ impl Parse for MacroSyntax {
})
}
}
+
+impl Parse for MacroSyntax {
+ fn parse(input: syn::parse::ParseStream) -> syn::Result {
+ Self::parse_syn(input, None)
+ }
+}
diff --git a/tests/macros.rs b/tests/macros.rs
index f8f2ea0..bcb013a 100644
--- a/tests/macros.rs
+++ b/tests/macros.rs
@@ -111,7 +111,11 @@ mod build_tests {
use std::fs;
use insta::{glob, Settings};
- use sabry::{usey, buildmagic::SabryBuilder, config::{BehavHashCollision, BehavSassModCollision, SabryConfig}};
+ use sabry::{
+ buildmagic::SabryBuilder,
+ config::{BehavHashCollision, BehavSassModCollision, SabryConfig},
+ usey,
+ };
fn gen_config() -> SabryConfig {
let mut config = SabryConfig::require().unwrap();