chore: pre0.1

This commit is contained in:
yiffyrusdev 2026-03-24 05:53:08 +05:00 • committed by spushk
commit 13cb7647ae
Signed by: spushk
GPG key ID: 7797B761E105E8AA
13 changed files with 114 additions and 238 deletions

View file

@ -1,5 +1,5 @@
[workspace] [workspace]
resolver = "2" resolver = "3"
members = [ members = [
"sabry_procmacro", "sabry_procmacro",
"sabry_procmacro_impl", "sabry_procmacro_impl",
@ -8,43 +8,42 @@ members = [
] ]
exclude = ["examples"] exclude = ["examples"]
[workspace.package]
version = "0.0.6"
edition = "2024"
rust-version = "1.88"
authors = ["Svyatoslav Pushkarev <yiffyrusdev@yandex.ru>"]
repository = "https://github.com/yiffyrusdev/sabry"
license = "MIT"
publish = true
[workspace.dependencies] [workspace.dependencies]
## Workspace ## Workspace
sabry_intrnl = { path = "sabry_intrnl", version = "0.0.6" } sabry_intrnl = { path = "sabry_intrnl", version = "0.0.6" }
sabry_procmacro = { path = "sabry_procmacro", version = "0.0.6" } sabry_procmacro = { path = "sabry_procmacro", version = "0.0.6" }
sabry_procmacro_impl = { path = "sabry_procmacro_impl", version = "0.0.6" } sabry_procmacro_impl = { path = "sabry_procmacro_impl", version = "0.0.6" }
sabry_build = { path = "sabry_build", version = "0.0.6" } sabry_build = { path = "sabry_build", version = "0.0.6" }
#/ ## CSS
lightningcss.version = "1.0.0-alpha.67" lightningcss.version = "1.0.0-alpha.71"
lightningcss.default-features = false lightningcss.default-features = false
grass.version = "^0.13" grass.version = "^0.13"
grass.default-features = false grass.default-features = false
raffia.version = "^0.11" raffia.version = "^0.12"
#/ ## Marshall
serde.version = "^1" serde.version = "^1"
toml.version = "^0.9" toml.version = "^1"
blake3.version = "^1"
base64.version = "^0.22" base64.version = "^0.22"
regex.version = "^1" regex.version = "^1"
#/ ## Util
itertools.version = "^0.14" itertools.version = "^0.14"
walkdir.version = "^2" walkdir.version = "^2"
#/ ## Codegen
cfg-if.version = "^1" cfg-if.version = "^1"
thiserror.version = "^2" thiserror.version = "^2"
proc-macro2.version = "^1" proc-macro2.version = "^1"
quote.version = "^1" quote.version = "^1"
syn.version = "^2" syn.version = "^2"
[workspace.package]
version = "0.0.6"
edition = "2021"
rust-version = "1.88"
authors = ["Svyatoslav Pushkarev <yiffyrusdev@yandex.ru>"]
repository = "https://github.com/yiffyrusdev/sabry"
license = "MIT"
publish = true
[package] [package]
name = "sabry" name = "sabry"
description = "Syntactically Awesome But RustY - crate that brings SCSS/SASS into rust" description = "Syntactically Awesome But RustY - crate that brings SCSS/SASS into rust"
@ -73,7 +72,6 @@ const-scoping = ["sabry_procmacro?/const-compile"]
procmacro = ["dep:sabry_procmacro"] procmacro = ["dep:sabry_procmacro"]
build = ["dep:sabry_build"] build = ["dep:sabry_build"]
net-files = ["sabry_build/net-files"] net-files = ["sabry_build/net-files"]
nightly = ["sabry_procmacro?/nightly"]
internals = [] internals = []
[package.metadata.docs.rs] [package.metadata.docs.rs]

View file

@ -1,7 +1,7 @@
[package] [package]
name = "define-styles" name = "define-styles"
version = "0.0.0" version = "0.0.0"
edition = "2021" edition = "2024"
rust-version = "1.88" rust-version = "1.88"
publish = false publish = false

View file

@ -2,25 +2,33 @@
name = "leptos-axum-sabry" name = "leptos-axum-sabry"
version = "0.1.0" version = "0.1.0"
rust-version = "1.88" rust-version = "1.88"
edition = "2021" edition = "2024"
publish = false publish = false
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
leptos = { version = "^0.8" } leptos.version = "^0.8"
leptos_axum = { version = "^0.8", optional = true } leptos_axum.version = "^0.8"
leptos_meta = { version = "^0.8" } leptos_axum.optional = true
leptos_router = { version = "^0.8" } leptos_meta.version = "^0.8"
axum = { version = "0.8", optional = true } leptos_router.version = "^0.8"
axum.version = "0.8"
axum.optional = true
console_error_panic_hook = "0.1" console_error_panic_hook = "0.1"
tokio = { version = "1", features = ["rt-multi-thread"], optional = true } tokio.version = "1"
tower = { version = "0.5", optional = true } tokio.features = ["rt-multi-thread"]
tower-http = { version = "0.6", features = ["fs"], optional = true } tokio.optional = true
wasm-bindgen = "=0.2.96" tower.version = "0.5"
tower.optional = true
tower-http.version = "0.6"
tower-http.features = ["fs"]
tower-http.optional = true
wasm-bindgen = "=0.2.114"
thiserror = "^1" thiserror = "^1"
tracing = { version = "0.1", optional = true } tracing.version = "0.1"
tracing.optional = true
http = "^1" http = "^1"
# sabry with sass # sabry with sass

View file

@ -2,16 +2,16 @@
name = "leptos-components" name = "leptos-components"
version = "0.1.0" version = "0.1.0"
rust-version = "1.88" rust-version = "1.88"
edition = "2021" edition = "2024"
publish = false publish = false
[lib] [lib]
crate-type = ["cdylib", "rlib"] crate-type = ["cdylib", "rlib"]
[dependencies] [dependencies]
leptos = { version = "^0.7" } leptos.version = "^0.8"
leptos_meta = { version = "^0.7" } leptos_meta.version = "^0.8"
leptos_router = { version = "^0.7" } leptos_router.version = "^0.8"
sabry = { path = "../../", features = ["const-scoping"] } sabry = { path = "../../", features = ["const-scoping"] }

View file

@ -1,7 +1,7 @@
[package] [package]
name = "use-styles" name = "use-styles"
version = "0.0.0" version = "0.0.0"
edition = "2021" edition = "2024"
rust-version = "1.88" rust-version = "1.88"
publish = false publish = false

View file

@ -11,14 +11,10 @@ license.workspace = true
[dependencies] [dependencies]
syn.workspace = true syn.workspace = true
raffia.workspace = true raffia.workspace = true
regex.workspace = true
regex.optional = true
grass.workspace = true grass.workspace = true
grass.optional = true grass.optional = true
lightningcss.workspace = true lightningcss.workspace = true
lightningcss.optional = true lightningcss.optional = true
blake3.workspace = true
blake3.optional = true
base64.workspace = true base64.workspace = true
base64.optional = true base64.optional = true
@ -29,7 +25,7 @@ toml.workspace = true
cfg-if.workspace = true cfg-if.workspace = true
[features] [features]
scope = ["dep:blake3", "dep:base64", "dep:regex"] scope = ["dep:base64"]
compile = ["dep:lightningcss", "dep:grass"] compile = ["dep:lightningcss", "dep:grass"]
[package.metadata.docs.rs] [package.metadata.docs.rs]

View file

@ -7,19 +7,20 @@ impl ScopeHash {
pub fn new(scope: &super::ArbitraryScope, config: &crate::config::SabryHashConfig) -> Self { pub fn new(scope: &super::ArbitraryScope, config: &crate::config::SabryHashConfig) -> Self {
use base64::Engine; use base64::Engine;
use raffia::ast::InterpolableIdent; use raffia::ast::InterpolableIdent;
use std::hash::Hasher;
use crate::scoper::apply_basic_rusty_member_gen_rules; use crate::scoper::sanitize_css_member;
let mut hasher = blake3::Hasher::new(); let mut hasher = std::hash::DefaultHasher::new();
if config.use_scope_name { if config.use_scope_name {
hasher.update(scope.name.to_string().as_bytes()); hasher.write(scope.name.to_string().as_bytes());
} }
if config.use_code_text { if config.use_code_text {
hasher.update(scope.adapter().source().as_bytes()); hasher.write(scope.adapter().source().as_bytes());
} }
if config.use_code_size { if config.use_code_size {
hasher.update(&scope.adapter().source().len().to_ne_bytes()); hasher.write(&scope.adapter().source().len().to_ne_bytes());
} }
if config.use_item_names { if config.use_item_names {
let classes = scope.adapter().class_selectors(); let classes = scope.adapter().class_selectors();
@ -38,22 +39,13 @@ impl ScopeHash {
.filter_map(|mbl| mbl.map(|l| l.raw)) .filter_map(|mbl| mbl.map(|l| l.raw))
.collect::<String>(); .collect::<String>();
hasher.update(merged_items.as_bytes()); hasher.write(merged_items.as_bytes());
} }
let size = if config.size >= blake3::OUT_LEN { let hash = hasher.finish().to_be_bytes();
blake3::OUT_LEN
} else {
config.size
};
let hash = hasher.finalize(); let hash = base64::prelude::BASE64_URL_SAFE_NO_PAD.encode(hash);
let hash = hash.as_bytes(); let hash = sanitize_css_member(&hash);
//? This isn't right. "size" is size of hash in symbols.
// naaah, its fine :D (Dan)
let hash = base64::prelude::BASE64_URL_SAFE_NO_PAD.encode(&hash[..size]);
let hash = apply_basic_rusty_member_gen_rules(&hash);
Self(hash) Self(hash)
} }

View file

@ -2,11 +2,11 @@ use std::fmt::Debug;
use hash::ScopeHash; use hash::ScopeHash;
use raffia::{ use raffia::{
ast::{InterpolableIdent, TypeSelector},
Span, Spanned, Span, Spanned,
ast::{InterpolableIdent, TypeSelector},
}; };
use crate::syntax::{ostrta::OneSyntaxToRuleThemAll, StylesheetAdapter}; use crate::syntax::{StylesheetAdapter, ostrta::OneSyntaxToRuleThemAll};
pub mod hash; pub mod hash;
@ -312,7 +312,7 @@ impl ScopedSelector {
#[cfg(feature = "scope")] #[cfg(feature = "scope")]
pub fn gen_rusty_ident(&self) -> Option<syn::Ident> { pub fn gen_rusty_ident(&self) -> Option<syn::Ident> {
let arb = &self.as_arbitrary().ident; let arb = &self.as_arbitrary().ident;
let basic = apply_basic_rusty_member_gen_rules(arb); let basic = sanitize_css_member(arb);
let ready = match self { let ready = match self {
Self::Class(_) => Some(basic), Self::Class(_) => Some(basic),
@ -376,34 +376,35 @@ impl ScopedSelector {
} }
#[cfg(feature = "scope")] #[cfg(feature = "scope")]
pub fn apply_basic_rusty_member_gen_rules(source: &str) -> String { pub fn sanitize_css_member(source: &str) -> String {
let omit_regex = regex::Regex::new(r"(^\-)|(\-$)|[^a-zA-Z0-9\-\_]") let mut target = String::with_capacity(source.len());
.expect("BUG: can not build omition regex for rusty member generation");
// omit forbidden chars
let cleaned = omit_regex.replace_all(source, "").to_string();
// other not-so-obvious rules
let mut target = String::with_capacity(cleaned.len());
let mut next_uppercase: bool = false; let mut next_uppercase: bool = false;
for (i, c) in cleaned.chars().enumerate() { for (i, c) in source
.chars()
.filter(|c| c.is_alphanumeric() || *c == '-')
.enumerate()
{
// first gidit is prepended with 'n' // first gidit is prepended with 'n'
if i == 0 && c.is_numeric() { if i == 0 && c.is_numeric() {
target.push('n'); target.push('n');
target.push(c); target.push(c);
continue; continue;
} }
// dash is omitted and next is uppercase if may be
// dash is omitted, replacing the next char with its uppercase
if c == '-' { if c == '-' {
next_uppercase = true; next_uppercase = true;
continue; continue;
} }
target.push(if next_uppercase {
let char = if next_uppercase {
next_uppercase = false; next_uppercase = false;
c.to_ascii_uppercase() c.to_ascii_uppercase()
} else { } else {
c c
}); };
target.push(char);
} }
target target
} }
@ -416,7 +417,7 @@ mod test {
use crate::{ use crate::{
config::SabryHashConfig, config::SabryHashConfig,
scoper::{hash::ScopeHash, HashedScope}, scoper::{HashedScope, hash::ScopeHash},
syntax::ostrta::OneSyntaxToRuleThemAll, syntax::ostrta::OneSyntaxToRuleThemAll,
}; };
@ -424,20 +425,11 @@ mod test {
#[test] #[test]
fn scope_hash_codegen() { fn scope_hash_codegen() {
let code = let code = ".cls1{color:red; &-dark{color: black;} #id1 {color:green;} div {color:blue;}} .cls3#id2{color: black;}";
".cls1{color:red; &-dark{color: black;} #id1 {color:green;} div {color:blue;}} .cls3#id2{color: black;}";
let hash = ScopeHash::test_init("F2kf8nMs".into()); let hash = ScopeHash::test_init("F2kf8nMs".into());
//cfg_if! {
//if #[cfg(feature = "lepty-scoping")]{
let expect_code = ".F2kf8nMs.cls1{color:red; &-dark{color: black;} #id1.F2kf8nMs {color:green;} div.F2kf8nMs {color:blue;}} .F2kf8nMs.cls3#id2.F2kf8nMs{color: black;}"; let expect_code = ".F2kf8nMs.cls1{color:red; &-dark{color: black;} #id1.F2kf8nMs {color:green;} div.F2kf8nMs {color:blue;}} .F2kf8nMs.cls3#id2.F2kf8nMs{color: black;}";
//} else {
// let expect_code = ".F2kf8nMs.cls1{color:red; &-dark{color: black;} #F2kf8nMs-id1 {color:green;} .F2kf8nMs div {color:blue;}} .F2kf8nMs.cls3#F2kf8nMs-id2{color: black;}";
//}
//}
// cfg_if! {
// if #[cfg(feature = "lepty-scoping")] {
let expect_selector_htmls = HashSet::from([ let expect_selector_htmls = HashSet::from([
"cls1".to_string(), "cls1".to_string(),
"id1".to_string(), "id1".to_string(),
@ -445,16 +437,6 @@ mod test {
"id2".to_string(), "id2".to_string(),
"".to_string(), // comes from `div` which has no html hashed code, still want to check presense "".to_string(), // comes from `div` which has no html hashed code, still want to check presense
]); ]);
// } else {
// let expect_selector_htmls = HashSet::from([
// "F2kf8nMs cls1".to_string(),
// "F2kf8nMs-id1".to_string(),
// "F2kf8nMs cls3".to_string(),
// "F2kf8nMs-id2".to_string(),
// "".to_string(), // comes from `div` which has no html hashed code, still want to check presense
// ]);
// }
//}
let scope = ArbitraryScope::from_source( let scope = ArbitraryScope::from_source(
OneSyntaxToRuleThemAll::Scss, OneSyntaxToRuleThemAll::Scss,

View file

@ -13,10 +13,8 @@ proc-macro = true
[dependencies] [dependencies]
sabry_procmacro_impl.workspace = true sabry_procmacro_impl.workspace = true
cfg-if.workspace = true
[features] [features]
nightly = []
const-compile = ["sabry_procmacro_impl/const-compile"] const-compile = ["sabry_procmacro_impl/const-compile"]
[package.metadata.docs.rs] [package.metadata.docs.rs]

View file

@ -1,9 +1,8 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
#![cfg_attr(feature = "nightly", feature(proc_macro_span))]
use std::path::PathBuf;
use std::str::FromStr; use std::str::FromStr;
use cfg_if::cfg_if;
use proc_macro::TokenStream; use proc_macro::TokenStream;
use sabry_procmacro_impl::impls::{ use sabry_procmacro_impl::impls::{
scssy::scssy_macro_impl, styly::styly_macro_impl, usey::usey_macro_impl, scssy::scssy_macro_impl, styly::styly_macro_impl, usey::usey_macro_impl,
@ -38,17 +37,8 @@ use sabry_procmacro_impl::impls::{
/// ///
#[proc_macro] #[proc_macro]
pub fn scssy(input: TokenStream) -> TokenStream { pub fn scssy(input: TokenStream) -> TokenStream {
cfg_if! { let source_path =
if #[cfg(feature = "nightly")] { PathBuf::from_str(&proc_macro::Span::call_site().file()).expect("Irrefutable result");
use proc_macro::Span;
use std::path::PathBuf;
let source_path = Some(PathBuf::from_str(
&Span::call_site().file()).expect("&str to be Infallible converted into PathBuf")
);
} else {
let source_path = None;
}
}
scssy_macro_impl(input.into(), source_path).into() scssy_macro_impl(input.into(), source_path).into()
} }
@ -111,18 +101,8 @@ pub fn scssy(input: TokenStream) -> TokenStream {
/// ``` /// ```
#[proc_macro] #[proc_macro]
pub fn styly(input: TokenStream) -> TokenStream { pub fn styly(input: TokenStream) -> TokenStream {
cfg_if! { let source_path =
if #[cfg(feature = "nightly")] { PathBuf::from_str(&proc_macro::Span::call_site().file()).expect("Irrefutable result");
use proc_macro::Span;
use std::path::PathBuf;
let source_path = Some(PathBuf::from_str(
&Span::call_site().file()).expect("&str to be Infallible converted into PathBuf")
);
} else {
let source_path = None;
}
}
styly_macro_impl(input.into(), source_path).into() styly_macro_impl(input.into(), source_path).into()
} }

View file

@ -1,10 +1,10 @@
use std::{fmt::Debug, fs, path::PathBuf, str::FromStr}; use std::{fmt::Debug, fs, path::PathBuf, str::FromStr};
use proc_macro2::{Span, TokenStream}; use proc_macro2::{Span, TokenStream};
use quote::{quote, ToTokens, TokenStreamExt}; use quote::{ToTokens, TokenStreamExt, quote};
use regex::Regex; use regex::Regex;
use sabry_intrnl::syntax::ostrta::OneSyntaxToRuleThemAll; use sabry_intrnl::syntax::ostrta::OneSyntaxToRuleThemAll;
use syn::{braced, parse::Parse, Ident, LitStr, Token}; use syn::{Ident, LitStr, Token, braced, parse::Parse};
pub mod scssy; pub mod scssy;
pub mod styly; pub mod styly;
@ -31,20 +31,15 @@ impl ArbitraryStyleBlock {
&self.code &self.code
} }
pub fn parse_syn( pub fn parse_syn(input: syn::parse::ParseStream, path_prefix: PathBuf) -> syn::Result<Self> {
input: syn::parse::ParseStream,
use_code_path_prefix: Option<PathBuf>,
) -> syn::Result<Self> {
let (code, span) = if let Ok(path_tok) = input.parse::<LitStr>() { let (code, span) = if let Ok(path_tok) = input.parse::<LitStr>() {
let path = if let Some(prefix) = use_code_path_prefix { let path = {
let p = path_tok.value(); let p = path_tok.value();
if let Some(pp) = p.strip_prefix("./") { if let Some(pp) = p.strip_prefix("./") {
prefix.join(pp) path_prefix.join(pp)
} else { } else {
PathBuf::from_str(&p).expect("Unable to convert path into PathBuf") PathBuf::from_str(&p).unwrap() // infallible
} }
} else {
PathBuf::from_str(&path_tok.value()).expect("Unable to convert path into PathBuf")
}; };
let fullpath = match path.canonicalize() { let fullpath = match path.canonicalize() {
@ -52,8 +47,11 @@ impl ArbitraryStyleBlock {
Err(e) => { Err(e) => {
return Err(syn::Error::new( return Err(syn::Error::new(
path_tok.span(), path_tok.span(),
format!("Could not use path {path:?}: {:?}. If the path is relative and 'nightly' feature flag is set - this is likely false-positive", 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()
),
));
} }
}; };
@ -63,7 +61,7 @@ impl ArbitraryStyleBlock {
return Err(syn::Error::new( return Err(syn::Error::new(
path_tok.span(), path_tok.span(),
format!("Could not read file at {fullpath:?}"), format!("Could not read file at {fullpath:?}"),
)) ));
} }
}; };
let code = String::from_utf8_lossy(&iofile).to_string(); let code = String::from_utf8_lossy(&iofile).to_string();
@ -79,7 +77,10 @@ impl ArbitraryStyleBlock {
let c = ident_regex.replace_all(&c, "\n").to_string(); let c = ident_regex.replace_all(&c, "\n").to_string();
(c, stream.span()) (c, stream.span())
} else { } else {
return Err(syn::Error::new(s.span(), "Use \"\" within the braces to specify your SASS/SCSS. Unquoted style syntax is reserved for the future. Unquoted SCSS/SASS doesnt make sense though, as you won't benefit from it in rust file.\n\ntip: use `{\"style\"}` instead of `{style}`")); return Err(syn::Error::new(
s.span(),
"Use \"\" within the braces to specify your SASS/SCSS. Unquoted style syntax is reserved for the future. Unquoted SCSS/SASS doesnt make sense though, as you won't benefit from it in rust file.\n\ntip: use `{\"style\"}` instead of `{style}`",
));
} }
}; };
@ -87,12 +88,6 @@ impl ArbitraryStyleBlock {
} }
} }
impl Parse for ArbitraryStyleBlock {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Self::parse_syn(input, None)
}
}
#[allow(clippy::to_string_trait_impl)] #[allow(clippy::to_string_trait_impl)]
impl ToString for ArbitraryStyleBlock { impl ToString for ArbitraryStyleBlock {
fn to_string(&self) -> String { fn to_string(&self) -> String {
@ -148,56 +143,3 @@ impl Parse for ArbitraryStyleSyntax {
} }
} }
} }
#[cfg(test)]
mod test {
#[test]
fn arbitrary_style_block_sass() {
use super::ArbitraryStyleBlock;
let code = "
#a
co: red
.sel
co: white
&-dark
& > div
co: blue";
let expect_code = "
#a
co: red
.sel
co: white
&-dark
& > div
co: blue";
let input = format!("{{\"{code}\"}}");
let block = syn::parse_str::<ArbitraryStyleBlock>(&input).unwrap();
assert_eq!(expect_code, block.code);
}
#[test]
fn arbitrary_style_block_scss() {
use super::ArbitraryStyleBlock;
let code = "
#a {
c: r;
}
.b.c {
c: 'into';
}";
let expect_code = "
#a {
c: r;
}
.b.c {
c: 'into';
}";
let input = format!("{{\"{code}\"}}");
let block = syn::parse_str::<ArbitraryStyleBlock>(&input).unwrap();
assert_eq!(expect_code, block.code)
}
}

View file

@ -3,10 +3,7 @@ use std::path::PathBuf;
use proc_macro2::TokenStream; use proc_macro2::TokenStream;
use quote::quote; use quote::quote;
use sabry_intrnl::scoper::ArbitraryScope; use sabry_intrnl::scoper::ArbitraryScope;
use syn::{ use syn::{Ident, parse::ParseStream};
parse::{Parse, ParseStream},
Ident,
};
use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax}; use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
@ -16,7 +13,7 @@ use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
/// `$syntax`: sass/scss /// `$syntax`: sass/scss
/// ///
/// `$code`: intended to be valid based on $syntax /// `$code`: intended to be valid based on $syntax
pub fn scssy_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> TokenStream { pub fn scssy_macro_impl(input: TokenStream, source_path: PathBuf) -> TokenStream {
let MacroSyntax { let MacroSyntax {
ident, ident,
syntax, syntax,
@ -36,7 +33,9 @@ pub fn scssy_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
} }
let sourcesass = code.to_string(); let sourcesass = code.to_string();
let macro_doc = format!("Arbitrary {syntax:?} code declared with `scssy!`. Pretty usable in tandem with `usey!` and `buildy` at build time"); let macro_doc = format!(
"Arbitrary {syntax:?} code declared with `scssy!`. Pretty usable in tandem with `usey!` and `buildy` at build time"
);
quote! { quote! {
#[doc = #macro_doc] #[doc = #macro_doc]
@ -55,17 +54,11 @@ pub struct MacroSyntax {
} }
impl MacroSyntax { impl MacroSyntax {
pub fn parse_syn( pub fn parse_syn(input: syn::parse::ParseStream, source_path: PathBuf) -> syn::Result<Self> {
input: syn::parse::ParseStream,
source_path: Option<PathBuf>,
) -> syn::Result<Self> {
let ident = input.parse::<Ident>()?; let ident = input.parse::<Ident>()?;
let syntax = input.parse::<ArbitraryStyleSyntax>()?; let syntax = input.parse::<ArbitraryStyleSyntax>()?;
let code = match source_path { let code = ArbitraryStyleBlock::parse_syn(input, source_path)?;
Some(sp) => ArbitraryStyleBlock::parse_syn(input, Some(sp))?,
None => input.parse::<ArbitraryStyleBlock>()?,
};
Ok(Self { Ok(Self {
ident, ident,
@ -75,11 +68,11 @@ impl MacroSyntax {
} }
} }
impl Parse for MacroSyntax { // impl Parse for MacroSyntax {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> { // fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Self::parse_syn(input, None) // Self::parse_syn(input, None)
} // }
} // }
#[cfg(test)] #[cfg(test)]
mod test {} mod test {}

View file

@ -6,11 +6,11 @@ use proc_macro2::{Span, TokenStream};
use quote::quote; use quote::quote;
use sabry_intrnl::{ use sabry_intrnl::{
config::SabryConfig, config::SabryConfig,
scoper::{apply_basic_rusty_member_gen_rules, ArbitraryScope, ScopedSelector}, scoper::{ArbitraryScope, ScopedSelector, sanitize_css_member},
}; };
use syn::{ use syn::{
parse::{Parse, ParseStream},
Ident, Token, Ident, Token,
parse::{Parse, ParseStream},
}; };
use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax}; use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
@ -32,7 +32,7 @@ use super::{ArbitraryStyleBlock, ArbitraryStyleSyntax};
/// ///
/// The machine-readable output may also be forced by use `machine_readable: true` arg on `parse_macro_syntax` function /// The machine-readable output may also be forced by use `machine_readable: true` arg on `parse_macro_syntax` function
/// without modifying tokenstream /// without modifying tokenstream
pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> TokenStream { pub fn styly_macro_impl(input: TokenStream, source_path: PathBuf) -> TokenStream {
let config = match SabryConfig::require() { let config = match SabryConfig::require() {
Ok(c) => c, Ok(c) => c,
Err(e) => { Err(e) => {
@ -40,7 +40,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
Span::call_site(), Span::call_site(),
format!("Could not read sabry configuration required by this macro: {e:?}",), format!("Could not read sabry configuration required by this macro: {e:?}",),
) )
.to_compile_error() .to_compile_error();
} }
}; };
let ms = match parse_macro_syntax(input, source_path) { let ms = match parse_macro_syntax(input, source_path) {
@ -62,7 +62,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
Span::call_site(), Span::call_site(),
format!("Could not generate scope: {e:?}"), format!("Could not generate scope: {e:?}"),
) )
.to_compile_error() .to_compile_error();
} }
}; };
@ -101,7 +101,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
}) })
.unique() .unique()
.map(|s| { .map(|s| {
let ident = apply_basic_rusty_member_gen_rules(&s); let ident = sanitize_css_member(&s);
let fnident = syn::parse_str::<Ident>(format!("_{ident}").as_str()) let fnident = syn::parse_str::<Ident>(format!("_{ident}").as_str())
.expect("BUG: invalid ident for nesting selector formed"); .expect("BUG: invalid ident for nesting selector formed");
let formatstr = format!("{{c}}{}", &s); let formatstr = format!("{{c}}{}", &s);
@ -223,7 +223,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
// reusable function, that does not return tokenstream for machine-processing at build time // reusable function, that does not return tokenstream for machine-processing at build time
pub fn parse_macro_syntax( pub fn parse_macro_syntax(
input: TokenStream, input: TokenStream,
source_path: Option<PathBuf>, source_path: PathBuf,
) -> Result<MacroSyntax, syn::Error> { ) -> Result<MacroSyntax, syn::Error> {
syn::parse::Parser::parse2( syn::parse::Parser::parse2(
|input: ParseStream<'_>| MacroSyntax::parse_syn(input, source_path), |input: ParseStream<'_>| MacroSyntax::parse_syn(input, source_path),
@ -263,18 +263,11 @@ pub struct MacroSyntax {
} }
impl MacroSyntax { impl MacroSyntax {
pub fn parse_syn( pub fn parse_syn(input: syn::parse::ParseStream, source_path: PathBuf) -> syn::Result<Self> {
input: syn::parse::ParseStream,
source_path: Option<PathBuf>,
) -> syn::Result<Self> {
let mut generator = input.parse::<ScopeGenerator>()?; let mut generator = input.parse::<ScopeGenerator>()?;
let scope = input.parse::<Ident>()?; let scope = input.parse::<Ident>()?;
let syntax = input.parse::<ArbitraryStyleSyntax>()?; let syntax = input.parse::<ArbitraryStyleSyntax>()?;
let code = if source_path.is_some() { let code = ArbitraryStyleBlock::parse_syn(input, source_path)?;
ArbitraryStyleBlock::parse_syn(input, source_path)
} else {
input.parse::<ArbitraryStyleBlock>()
}?;
if input.parse::<Token![#]>().is_ok() { if input.parse::<Token![#]>().is_ok() {
generator = ScopeGenerator::MachineReadable generator = ScopeGenerator::MachineReadable
@ -288,9 +281,3 @@ impl MacroSyntax {
}) })
} }
} }
impl Parse for MacroSyntax {
fn parse(input: syn::parse::ParseStream) -> syn::Result<Self> {
Self::parse_syn(input, None)
}
}