breaking: gate 'styly!(const scope...' behind the const-scoping feature.\nFor some reason it did only become a problem recently, but it appears that having lightningcss/grass unconditionally will break WASM builds by having getrandom dependency
This commit is contained in:
parent
247774d9a4
commit
80890500c9
14 changed files with 150 additions and 97 deletions
25
Cargo.toml
25
Cargo.toml
|
|
@ -4,10 +4,33 @@ members = ["sabry_procmacro", "sabry_procmacro_impl", "sabry_intrnl"]
|
|||
exclude = ["examples"]
|
||||
|
||||
[workspace.dependencies]
|
||||
## Workspace
|
||||
sabry_intrnl = { path = "sabry_intrnl", version = "0.0.5" }
|
||||
sabry_procmacro = { path = "sabry_procmacro", version = "0.0.5" }
|
||||
sabry_procmacro_impl = { path = "sabry_procmacro_impl", version = "0.0.5" }
|
||||
sabry_build = { path = "sabry_build", version = "0.0.5" }
|
||||
## Package
|
||||
## Package
|
||||
lightningcss.version = "1.0.0-alpha.65"
|
||||
lightningcss.default-features = false
|
||||
grass.version = "^0.13"
|
||||
grass.default-features = false
|
||||
raffia.version = "^0.9"
|
||||
#/
|
||||
serde.version = "^1"
|
||||
toml.version = "^0.8"
|
||||
blake3.version = "^1"
|
||||
base64.version = "^0.22"
|
||||
regex.version = "^1"
|
||||
#/
|
||||
itertools.version = "^0.14"
|
||||
walkdir.version = "^2"
|
||||
#/
|
||||
cfg-if.version = "^1"
|
||||
thiserror.version = "^2"
|
||||
proc-macro2.version = "^1"
|
||||
quote.version = "^1"
|
||||
syn.version = "^2"
|
||||
|
||||
[workspace.package]
|
||||
version = "0.0.5"
|
||||
|
|
@ -31,6 +54,7 @@ license.workspace = true
|
|||
publish.workspace = true
|
||||
|
||||
[dependencies]
|
||||
## Workspace
|
||||
sabry_procmacro = { workspace = true, optional = true }
|
||||
sabry_build = { workspace = true, optional = true }
|
||||
sabry_intrnl = { workspace = true }
|
||||
|
|
@ -42,6 +66,7 @@ insta = { version = "^1.41", features = ["glob"] }
|
|||
[features]
|
||||
default = ["procmacro"]
|
||||
lepty-scoping = ["sabry_intrnl/lepty-scoping"]
|
||||
const-scoping = ["sabry_procmacro?/const-compile"]
|
||||
procmacro = ["dep:sabry_procmacro"]
|
||||
build = ["dep:sabry_build"]
|
||||
net-files = ["sabry_build/net-files"]
|
||||
|
|
|
|||
|
|
@ -8,9 +8,6 @@
|
|||
>
|
||||
> "master" branch is what's currently on crates.io
|
||||
>
|
||||
> each version ever been on crates.io (except the latest release) is available in "vX.X.X" branch
|
||||
>
|
||||
> the latest-trashy state is in the "window" branch
|
||||
|
||||
[](https://crates.io/crates/sabry)
|
||||
[](https://docs.rs/sabry)
|
||||
|
|
@ -586,6 +583,7 @@ As you've seen above, scope doe not contain any style code by itself. That's the
|
|||
However you could still compile styles into the artifact by simply adding the `const` to the macro call:
|
||||
|
||||
```rust
|
||||
// Requires `const-scoping` feature
|
||||
sabry::styly!(const scope "tests/assets/mixin-module.scss");
|
||||
```
|
||||
Which results in following:
|
||||
|
|
|
|||
|
|
@ -13,19 +13,19 @@ leptos = { version = "^0.7" }
|
|||
leptos_meta = { version = "^0.7" }
|
||||
leptos_router = { version = "^0.7" }
|
||||
|
||||
sabry = {path = "../../", features = ["lepty-scoping"]}
|
||||
sabry = { path = "../../", features = ["lepty-scoping", "const-scoping"] }
|
||||
|
||||
[build-dependencies]
|
||||
sabry = {path = "../../", features = ["build", "lepty-scoping"]}
|
||||
define-styles = {path = "../define-styles"}
|
||||
sabry = { path = "../../", features = [
|
||||
"build",
|
||||
"lepty-scoping",
|
||||
"const-scoping",
|
||||
] }
|
||||
define-styles = { path = "../define-styles" }
|
||||
|
||||
[features]
|
||||
hydrate = ["leptos/hydrate"]
|
||||
ssr = [
|
||||
"leptos/ssr",
|
||||
"leptos_meta/ssr",
|
||||
"leptos_router/ssr",
|
||||
]
|
||||
ssr = ["leptos/ssr", "leptos_meta/ssr", "leptos_router/ssr"]
|
||||
|
||||
[package.metadata.sabry]
|
||||
css.minify = true
|
||||
|
|
|
|||
|
|
@ -9,13 +9,17 @@ authors.workspace = true
|
|||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
sabry_intrnl = { workspace = true }
|
||||
sabry_procmacro_impl = { workspace = true }
|
||||
sabry_intrnl.workspace = true
|
||||
sabry_intrnl.features = ["compile", "scope"]
|
||||
sabry_procmacro_impl.workspace = true
|
||||
sabry_procmacro_impl.features = ["const-compile"]
|
||||
|
||||
syn = { version = "^2", features = ["visit", "derive", "parsing", "full"] }
|
||||
proc-macro2 = { version = "^1", features = ["span-locations"] }
|
||||
thiserror = { version = "^2" }
|
||||
walkdir = { version = "^2" }
|
||||
syn.workspace = true
|
||||
syn.features = ["visit", "derive", "parsing", "full"]
|
||||
proc-macro2.workspace = true
|
||||
proc-macro2.features = ["span-locations"]
|
||||
thiserror.workspace = true
|
||||
walkdir.workspace = true
|
||||
|
||||
[features]
|
||||
net-files = []
|
||||
|
|
|
|||
|
|
@ -9,21 +9,30 @@ authors.workspace = true
|
|||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
syn = { version = "^2" }
|
||||
raffia = { version = "^0.9" }
|
||||
regex = { version = "^1" }
|
||||
grass = { version = "^0.13" }
|
||||
lightningcss = { version = "1.0.0-alpha.65" }
|
||||
blake3 = { version = "^1.5" }
|
||||
base64 = { version = "^0.22" }
|
||||
syn.workspace = true
|
||||
raffia.workspace = true
|
||||
regex.workspace = true
|
||||
regex.optional = true
|
||||
grass.workspace = true
|
||||
grass.optional = true
|
||||
lightningcss.workspace = true
|
||||
lightningcss.features = ["grid"]
|
||||
lightningcss.optional = true
|
||||
blake3.workspace = true
|
||||
blake3.optional = true
|
||||
base64.workspace = true
|
||||
base64.optional = true
|
||||
|
||||
thiserror = { version = "^2" }
|
||||
serde = { version = "^1", features = ["derive"] }
|
||||
toml = { version = "^0.8" }
|
||||
cfg-if = { version = "^1" }
|
||||
thiserror.workspace = true
|
||||
serde.workspace = true
|
||||
serde.features = ["derive"]
|
||||
toml.workspace = true
|
||||
cfg-if.workspace = true
|
||||
|
||||
[features]
|
||||
lepty-scoping = []
|
||||
scope = ["dep:blake3", "dep:base64", "dep:regex"]
|
||||
compile = ["dep:lightningcss", "dep:grass"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
|
|||
|
|
@ -1,16 +1,8 @@
|
|||
use std::fmt::Debug;
|
||||
|
||||
use lightningcss::{
|
||||
error::{MinifyErrorKind, PrinterErrorKind},
|
||||
printer::PrinterOptions,
|
||||
stylesheet::MinifyOptions,
|
||||
targets::Targets,
|
||||
};
|
||||
|
||||
use crate::{config::SabryConfig, syntax::ostrta::OneSyntaxToRuleThemAll};
|
||||
use crate::config::SabryConfig;
|
||||
|
||||
/// Convenience wrapper on Grass and Lightningcss
|
||||
pub struct CompilerAdapter {
|
||||
#[allow(dead_code)] // without 'compile' feature, still want to set this
|
||||
config: SabryConfig,
|
||||
}
|
||||
|
||||
|
|
@ -21,9 +13,10 @@ impl CompilerAdapter {
|
|||
|
||||
/// Compile given SASS/SCSS into CSS
|
||||
/// with respect to self.config
|
||||
#[cfg(feature = "compile")]
|
||||
pub fn compile_module(
|
||||
&self,
|
||||
syntax: OneSyntaxToRuleThemAll,
|
||||
syntax: crate::syntax::ostrta::OneSyntaxToRuleThemAll,
|
||||
code: &str,
|
||||
) -> Result<String, SabryCompilerError> {
|
||||
let options = grass::Options::from(&self.config).input_syntax(syntax.into());
|
||||
|
|
@ -35,7 +28,10 @@ impl CompilerAdapter {
|
|||
|
||||
/// Perform lightningcss transformations on given css
|
||||
/// with respect to self.config.css.minify on minification
|
||||
#[cfg(feature = "compile")]
|
||||
pub fn lightningcss(&self, css: &str) -> Result<String, SabryCompilerError> {
|
||||
use lightningcss::{printer::PrinterOptions, stylesheet::MinifyOptions, targets::Targets};
|
||||
|
||||
let mut lightsheet = match lightningcss::stylesheet::StyleSheet::parse(
|
||||
css,
|
||||
lightningcss::stylesheet::ParserOptions::default(),
|
||||
|
|
@ -81,6 +77,7 @@ impl CompilerAdapter {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "compile")]
|
||||
impl From<&SabryConfig> for grass::Options<'_> {
|
||||
fn from(config: &SabryConfig) -> Self {
|
||||
let mut options = grass::Options::default();
|
||||
|
|
@ -95,14 +92,15 @@ impl From<&SabryConfig> for grass::Options<'_> {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "compile")]
|
||||
#[derive(thiserror::Error)]
|
||||
pub enum SabryCompilerError {
|
||||
#[error("Could not compile into CSS with grass")]
|
||||
GrassCompile(#[from] Box<grass::Error>),
|
||||
#[error("Could not print compiled CSS with lightningcss")]
|
||||
LightPrint(#[from] lightningcss::error::Error<PrinterErrorKind>),
|
||||
LightPrint(#[from] lightningcss::error::Error<lightningcss::error::PrinterErrorKind>),
|
||||
#[error("Could not minify CSS with lightningcss")]
|
||||
LightMinify(#[from] lightningcss::error::Error<MinifyErrorKind>),
|
||||
LightMinify(#[from] lightningcss::error::Error<lightningcss::error::MinifyErrorKind>),
|
||||
#[error("Could not parse CSS with lightningcss")]
|
||||
LightParse {
|
||||
kind: String,
|
||||
|
|
@ -110,7 +108,8 @@ pub enum SabryCompilerError {
|
|||
},
|
||||
}
|
||||
|
||||
impl Debug for SabryCompilerError {
|
||||
#[cfg(feature = "compile")]
|
||||
impl std::fmt::Debug for SabryCompilerError {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
let explain = match self {
|
||||
Self::LightPrint(e) => format!(
|
||||
|
|
|
|||
|
|
@ -199,6 +199,7 @@ impl SabryLightTargets {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "compile")]
|
||||
impl From<SabryLightTargets> for lightningcss::targets::Browsers {
|
||||
fn from(value: SabryLightTargets) -> Self {
|
||||
Self {
|
||||
|
|
|
|||
|
|
@ -1,15 +1,14 @@
|
|||
use base64::Engine;
|
||||
|
||||
use crate::config::SabryHashConfig;
|
||||
|
||||
use super::{apply_basic_rusty_member_gen_rules, ArbitraryScope};
|
||||
|
||||
/// Convenience wrapper for String-being-a-hash
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub struct ScopeHash(String);
|
||||
|
||||
impl ScopeHash {
|
||||
pub fn new(scope: &ArbitraryScope, config: &SabryHashConfig) -> Self {
|
||||
#[cfg(feature = "scope")]
|
||||
pub fn new(scope: &super::ArbitraryScope, config: &crate::config::SabryHashConfig) -> Self {
|
||||
use base64::Engine;
|
||||
|
||||
use crate::scoper::apply_basic_rusty_member_gen_rules;
|
||||
|
||||
let mut hasher = blake3::Hasher::new();
|
||||
|
||||
if config.use_scope_name {
|
||||
|
|
|
|||
|
|
@ -3,12 +3,8 @@ use std::fmt::Debug;
|
|||
use cfg_if::cfg_if;
|
||||
use hash::ScopeHash;
|
||||
use raffia::{Span, Spanned};
|
||||
use regex::Regex;
|
||||
|
||||
use crate::{
|
||||
config::SabryHashConfig,
|
||||
syntax::{ostrta::OneSyntaxToRuleThemAll, StylesheetAdapter},
|
||||
};
|
||||
use crate::syntax::{ostrta::OneSyntaxToRuleThemAll, StylesheetAdapter};
|
||||
|
||||
pub mod hash;
|
||||
|
||||
|
|
@ -56,7 +52,11 @@ impl<'s> ArbitraryScope<'s> {
|
|||
/// Consume arbitrary scope and create a [HashedScope] in its basis
|
||||
///
|
||||
/// This function calls [HashedScope::new] under the hood
|
||||
pub fn hashed(self, config: &SabryHashConfig) -> Result<HashedScope<'s>, ScopeError> {
|
||||
#[cfg(feature = "scope")]
|
||||
pub fn hashed(
|
||||
self,
|
||||
config: &crate::config::SabryHashConfig,
|
||||
) -> Result<HashedScope<'s>, ScopeError> {
|
||||
let hash = ScopeHash::new(&self, config);
|
||||
HashedScope::new(hash, self)
|
||||
}
|
||||
|
|
@ -332,6 +332,7 @@ impl ScopedSelector {
|
|||
}
|
||||
|
||||
/// Generate rusty member ident based on selector type and CSS ident
|
||||
#[cfg(feature = "scope")]
|
||||
pub fn gen_rusty_ident(&self) -> Option<syn::Ident> {
|
||||
let arb = &self.as_arbitrary().ident;
|
||||
let basic = apply_basic_rusty_member_gen_rules(arb);
|
||||
|
|
@ -401,8 +402,9 @@ impl ScopedSelector {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "scope")]
|
||||
pub fn apply_basic_rusty_member_gen_rules(source: &str) -> String {
|
||||
let omit_regex = Regex::new(r"(^\-)|(\-$)|[^a-zA-Z0-9\-\_]")
|
||||
let omit_regex = regex::Regex::new(r"(^\-)|(\-$)|[^a-zA-Z0-9\-\_]")
|
||||
.expect("BUG: can not build omition regex for rusty member generation");
|
||||
|
||||
// omit forbidden chars
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ impl TryFrom<raffia::Syntax> for OneSyntaxToRuleThemAll {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "compile")]
|
||||
impl TryFrom<grass::InputSyntax> for OneSyntaxToRuleThemAll {
|
||||
type Error = ();
|
||||
fn try_from(value: grass::InputSyntax) -> Result<Self, Self::Error> {
|
||||
|
|
@ -54,6 +55,7 @@ impl From<OneSyntaxToRuleThemAll> for raffia::Syntax {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "compile")]
|
||||
impl From<OneSyntaxToRuleThemAll> for grass::InputSyntax {
|
||||
fn from(value: OneSyntaxToRuleThemAll) -> Self {
|
||||
match value {
|
||||
|
|
|
|||
|
|
@ -12,11 +12,12 @@ license.workspace = true
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
sabry_procmacro_impl = { workspace = true }
|
||||
cfg-if = { version = "^1" }
|
||||
sabry_procmacro_impl.workspace = true
|
||||
cfg-if.workspace = true
|
||||
|
||||
[features]
|
||||
nightly = []
|
||||
const-compile = ["sabry_procmacro_impl/const-compile"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
|
|||
|
|
@ -9,15 +9,20 @@ authors.workspace = true
|
|||
license.workspace = true
|
||||
|
||||
[dependencies]
|
||||
sabry_intrnl = { workspace = true }
|
||||
syn = { version = "^2", features = ["parsing"] }
|
||||
quote = { version = "^1" }
|
||||
proc-macro2 = { version = "^1", features = ["span-locations"] }
|
||||
regex = { version = "^1" }
|
||||
itertools = { version = "^0.14" }
|
||||
sabry_intrnl.workspace = true
|
||||
sabry_intrnl.features = ["scope"]
|
||||
syn.workspace = true
|
||||
syn.features = ["parsing"]
|
||||
quote.workspace = true
|
||||
proc-macro2.workspace = true
|
||||
proc-macro2.features = ["span-locations"]
|
||||
regex.workspace = true
|
||||
itertools.workspace = true
|
||||
cfg-if.workspace = true
|
||||
|
||||
[features]
|
||||
nightly = []
|
||||
const-compile = ["sabry_intrnl/compile"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ pub fn scssy_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
|
|||
}
|
||||
|
||||
let sourcesass = code.to_string();
|
||||
let macro_doc = format!("Arbitrary {:?} code declared with `scssy!`. Pretty usable in tandem with `usey!` and `buildy` at build time", syntax);
|
||||
let macro_doc = format!("Arbitrary {syntax:?} code declared with `scssy!`. Pretty usable in tandem with `usey!` and `buildy` at build time");
|
||||
|
||||
quote! {
|
||||
#[doc = #macro_doc]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
use std::path::PathBuf;
|
||||
|
||||
use cfg_if::cfg_if;
|
||||
use itertools::Itertools;
|
||||
use proc_macro2::{Span, TokenStream};
|
||||
use quote::quote;
|
||||
use sabry_intrnl::{
|
||||
compiler::CompilerAdapter,
|
||||
config::SabryConfig,
|
||||
scoper::{apply_basic_rusty_member_gen_rules, ArbitraryScope, ScopedSelector},
|
||||
};
|
||||
|
|
@ -38,10 +38,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
|
|||
Err(e) => {
|
||||
return syn::Error::new(
|
||||
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()
|
||||
}
|
||||
|
|
@ -63,7 +60,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
|
|||
Err(e) => {
|
||||
return syn::Error::new(
|
||||
Span::call_site(),
|
||||
format!("Could not generate scope: {:?}", e),
|
||||
format!("Could not generate scope: {e:?}"),
|
||||
)
|
||||
.to_compile_error()
|
||||
}
|
||||
|
|
@ -127,7 +124,7 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
|
|||
})
|
||||
})
|
||||
.map(|(name, ident, html, css)| {
|
||||
let docs = format!("'{:?}' {}. CSS selector '{}'", ident, name, css);
|
||||
let docs = format!("'{ident:?}' {name}. CSS selector '{css}'");
|
||||
quote! {
|
||||
#[doc = #docs]
|
||||
#[allow(non_upper_case_globals)]
|
||||
|
|
@ -142,6 +139,9 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
|
|||
let wrp_docs = format!("wrapper class for '{}' scope. If you have any tagname selectors - they should live as children of element with this class applied.", &scope_ident);
|
||||
|
||||
if constant {
|
||||
cfg_if! {
|
||||
if #[cfg(feature = "const-compile")] {
|
||||
use sabry_intrnl::compiler::CompilerAdapter;
|
||||
let compiler = CompilerAdapter::new(config.clone());
|
||||
let css = match compiler.compile_module(ms.syntax.0, &scope.hashed_code) {
|
||||
Ok(c) => c,
|
||||
|
|
@ -171,6 +171,14 @@ pub fn styly_macro_impl(input: TokenStream, source_path: Option<PathBuf>) -> Tok
|
|||
#(#special_nesting_members)*
|
||||
}
|
||||
}
|
||||
} else {
|
||||
return syn::Error::new(
|
||||
Span::call_site(),
|
||||
"`styly!(const scope...` requires `experimental-const-scoping` feature flag",
|
||||
)
|
||||
.to_compile_error();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
quote! {
|
||||
#[doc = #wrp_docs]
|
||||
|
|
|
|||
Loading…
Reference in a new issue