tail_merge 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/ext/tail_merge/src/lib.rs +93 -19
- data/lib/tail_merge/version.rb +1 -1
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff6ca50c862b6942ab07296b4111bc84928f960883f939e153069b926b51dc38
|
4
|
+
data.tar.gz: 853009b24fb888e2d0af540c274541fdebbad87aded06fbab79cfcb1061f469a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: dc1d28edcf9b35ea2b98ba0a42821d932ad8109c21e818fa6b499fc8cdbca2db4dbe8c54540fb4d8c79dca2523f90a5883398e8736e4ef9f7693e855c956369c
|
7
|
+
data.tar.gz: 385cea35eb5451eb138557b3ec3312834fc4826449802f16f7f40531922ca38dc9fdd55c829fcdcc819820b7196cd10a26095ae65b5f252fc3c830d9eb380fdd
|
data/ext/tail_merge/src/lib.rs
CHANGED
@@ -1,33 +1,107 @@
|
|
1
|
-
use magnus::{
|
1
|
+
use magnus::{
|
2
|
+
define_module, function, prelude::*, Error, RArray, RHash, RString, Ruby, Value,
|
3
|
+
};
|
2
4
|
use rustui_merge::merge::tw_merge;
|
3
5
|
|
4
|
-
fn merge_tailwind_classes(
|
5
|
-
|
6
|
-
|
7
|
-
if let Ok(rstring) = arg.clone().try_convert::<RString>() {
|
8
|
-
// If it's a string, split on spaces
|
9
|
-
let s = rstring.to_string()?;
|
10
|
-
class_strings.extend(s.split_whitespace().map(|s| s.to_string()));
|
11
|
-
} else if let Ok(rarray) = arg.try_convert::<RArray>() {
|
12
|
-
// If it's an array, process as before
|
13
|
-
for arg in rarray.each() {
|
14
|
-
let rstring: RString = arg?.try_convert()?;
|
15
|
-
class_strings.push(rstring.to_string()?);
|
16
|
-
}
|
17
|
-
} else {
|
6
|
+
fn merge_tailwind_classes(args: &[Value]) -> Result<RString, Error> {
|
7
|
+
// ---------- 1. arity ----------------------------------------------------
|
8
|
+
if args.is_empty() || args.len() > 2 {
|
18
9
|
return Err(Error::new(
|
19
|
-
magnus::exception::
|
20
|
-
"
|
10
|
+
magnus::exception::arg_error(),
|
11
|
+
"wrong number of arguments (expected 1 or 2)",
|
21
12
|
));
|
22
13
|
}
|
23
14
|
|
24
|
-
|
15
|
+
// ---------- 2. collect class tokens ------------------------------------
|
16
|
+
let mut tokens = Vec::<String>::new();
|
17
|
+
match args[0].clone().try_convert::<RString>() {
|
18
|
+
Ok(rstr) => tokens.extend(rstr.to_string()?.split_whitespace().map(str::to_owned)),
|
19
|
+
Err(_) => {
|
20
|
+
let rarray: RArray = args[0].try_convert()?;
|
21
|
+
for v in rarray.each() {
|
22
|
+
let s: RString = v?.try_convert()?;
|
23
|
+
tokens.push(s.to_string()?);
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
|
28
|
+
// ---------- 3. extract options -----------------------------------------
|
29
|
+
let mut prefix: Option<String> = None;
|
30
|
+
let mut separator: Option<String> = None;
|
31
|
+
|
32
|
+
if args.len() == 2 {
|
33
|
+
let rhash: RHash = args[1].try_convert()?;
|
34
|
+
let ruby = Ruby::get().unwrap();
|
35
|
+
|
36
|
+
if let Some(v) = rhash.get(ruby.to_symbol("prefix")) {
|
37
|
+
let s: RString = v.try_convert()?;
|
38
|
+
prefix = Some(s.to_string()?);
|
39
|
+
}
|
40
|
+
if let Some(v) = rhash.get(ruby.to_symbol("separator")) {
|
41
|
+
let s: RString = v.try_convert()?;
|
42
|
+
separator = Some(s.to_string()?);
|
43
|
+
}
|
44
|
+
}
|
45
|
+
|
46
|
+
// ---------- 4. merge ----------------------------------------------------
|
47
|
+
let merged = if let Some(pref) = prefix {
|
48
|
+
// split based on whether the last segment starts with the prefix
|
49
|
+
let mut with_pref = Vec::new();
|
50
|
+
let mut without_pref = Vec::new();
|
51
|
+
|
52
|
+
for t in tokens {
|
53
|
+
let base = t.rsplit_once(':').map(|(_, b)| b).unwrap_or(&t);
|
54
|
+
if base.starts_with(&pref) {
|
55
|
+
// strip prefix after variant(s)
|
56
|
+
let stripped = if let Some((v, b)) = t.rsplit_once(':') {
|
57
|
+
format!("{}:{}", v, &b[pref.len()..])
|
58
|
+
} else {
|
59
|
+
(&t[pref.len()..]).to_owned()
|
60
|
+
};
|
61
|
+
with_pref.push(stripped);
|
62
|
+
} else {
|
63
|
+
without_pref.push(t);
|
64
|
+
}
|
65
|
+
}
|
66
|
+
|
67
|
+
let mut out = Vec::new();
|
68
|
+
if !without_pref.is_empty() {
|
69
|
+
out.extend(
|
70
|
+
tw_merge(without_pref.join(" "))
|
71
|
+
.split_whitespace()
|
72
|
+
.map(str::to_owned),
|
73
|
+
);
|
74
|
+
}
|
75
|
+
if !with_pref.is_empty() {
|
76
|
+
out.extend(
|
77
|
+
tw_merge(with_pref.join(" "))
|
78
|
+
.split_whitespace()
|
79
|
+
.map(|s| {
|
80
|
+
// re-attach prefix
|
81
|
+
if let Some((v, b)) = s.rsplit_once(':') {
|
82
|
+
format!("{}:{}{}", v, &pref, b)
|
83
|
+
} else {
|
84
|
+
format!("{}{}", pref, s)
|
85
|
+
}
|
86
|
+
}),
|
87
|
+
);
|
88
|
+
}
|
89
|
+
out.join(" ")
|
90
|
+
} else if separator.is_some() {
|
91
|
+
// at the moment we can't apply per-call separators without global state;
|
92
|
+
// fall back to the default behaviour.
|
93
|
+
tw_merge(tokens.join(" "))
|
94
|
+
} else {
|
95
|
+
tw_merge(tokens.join(" "))
|
96
|
+
};
|
97
|
+
|
25
98
|
Ok(RString::new(&merged))
|
26
99
|
}
|
27
100
|
|
28
101
|
#[magnus::init]
|
29
102
|
fn init() -> Result<(), Error> {
|
30
103
|
let module = define_module("TailMerge")?;
|
31
|
-
|
104
|
+
// -1 = variable arity (positional + kw-hash)
|
105
|
+
module.define_singleton_method("merge", function!(merge_tailwind_classes, -1))?;
|
32
106
|
Ok(())
|
33
107
|
}
|
data/lib/tail_merge/version.rb
CHANGED