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
3 changed files with 114 additions and 238 deletions

View file

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

View file

@ -7,19 +7,20 @@ impl ScopeHash {
pub fn new(scope: &super::ArbitraryScope, config: &crate::config::SabryHashConfig) -> Self {
use base64::Engine;
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 {
hasher.update(scope.name.to_string().as_bytes());
hasher.write(scope.name.to_string().as_bytes());
}
if config.use_code_text {
hasher.update(scope.adapter().source().as_bytes());
hasher.write(scope.adapter().source().as_bytes());
}
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 {
let classes = scope.adapter().class_selectors();
@ -38,22 +39,13 @@ impl ScopeHash {
.filter_map(|mbl| mbl.map(|l| l.raw))
.collect::<String>();
hasher.update(merged_items.as_bytes());
hasher.write(merged_items.as_bytes());
}
let size = if config.size >= blake3::OUT_LEN {
blake3::OUT_LEN
} else {
config.size
};
let hash = hasher.finish().to_be_bytes();
let hash = hasher.finalize();
let hash = hash.as_bytes();
//? 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);
let hash = base64::prelude::BASE64_URL_SAFE_NO_PAD.encode(hash);
let hash = sanitize_css_member(&hash);
Self(hash)
}

View file

@ -2,11 +2,11 @@ use std::fmt::Debug;
use hash::ScopeHash;
use raffia::{
ast::{InterpolableIdent, TypeSelector},
Span, Spanned,
ast::{InterpolableIdent, TypeSelector},
};
use crate::syntax::{ostrta::OneSyntaxToRuleThemAll, StylesheetAdapter};
use crate::syntax::{StylesheetAdapter, ostrta::OneSyntaxToRuleThemAll};
pub mod hash;
@ -312,7 +312,7 @@ impl ScopedSelector {
#[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);
let basic = sanitize_css_member(arb);
let ready = match self {
Self::Class(_) => Some(basic),
@ -376,34 +376,35 @@ impl ScopedSelector {
}
#[cfg(feature = "scope")]
pub fn apply_basic_rusty_member_gen_rules(source: &str) -> String {
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
let cleaned = omit_regex.replace_all(source, "").to_string();
// other not-so-obvious rules
let mut target = String::with_capacity(cleaned.len());
pub fn sanitize_css_member(source: &str) -> String {
let mut target = String::with_capacity(source.len());
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'
if i == 0 && c.is_numeric() {
target.push('n');
target.push(c);
continue;
}
// dash is omitted and next is uppercase if may be
// dash is omitted, replacing the next char with its uppercase
if c == '-' {
next_uppercase = true;
continue;
}
target.push(if next_uppercase {
let char = if next_uppercase {
next_uppercase = false;
c.to_ascii_uppercase()
} else {
c
});
};
target.push(char);
}
target
}
@ -416,7 +417,7 @@ mod test {
use crate::{
config::SabryHashConfig,
scoper::{hash::ScopeHash, HashedScope},
scoper::{HashedScope, hash::ScopeHash},
syntax::ostrta::OneSyntaxToRuleThemAll,
};
@ -424,20 +425,11 @@ mod test {
#[test]
fn scope_hash_codegen() {
let code =
".cls1{color:red; &-dark{color: black;} #id1 {color:green;} div {color:blue;}} .cls3#id2{color: black;}";
let code = ".cls1{color:red; &-dark{color: black;} #id1 {color:green;} div {color:blue;}} .cls3#id2{color: black;}";
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;}";
//} 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([
"cls1".to_string(),
"id1".to_string(),
@ -445,16 +437,6 @@ mod test {
"id2".to_string(),
"".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(
OneSyntaxToRuleThemAll::Scss,