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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3aa2748d158cbcc46f8db818a6f1dbf5c0f3b210f03b48b96b178ee4e8d4c25c
4
- data.tar.gz: fae3b047cf0136529135c371bae6ecdf4172bdb7f96bed1e16821a41decc9343
3
+ metadata.gz: ff6ca50c862b6942ab07296b4111bc84928f960883f939e153069b926b51dc38
4
+ data.tar.gz: 853009b24fb888e2d0af540c274541fdebbad87aded06fbab79cfcb1061f469a
5
5
  SHA512:
6
- metadata.gz: ec9ef9dc0dc7f40e77fbc5ae416abdf1054a959465e5cbd22a86ecefbc6b86454ef4c416833b8c35dbc41749c5fbfa9d8b10a9e1720dba741d1ee51742d68f8d
7
- data.tar.gz: c9210f053328369aa0b25a3e9f14f87a011b84c85f33f65d2a8e5962efccb7a83698cba71b824cc522469f596da2eab7c0701bd931ba0de088620cada7192914
6
+ metadata.gz: dc1d28edcf9b35ea2b98ba0a42821d932ad8109c21e818fa6b499fc8cdbca2db4dbe8c54540fb4d8c79dca2523f90a5883398e8736e4ef9f7693e855c956369c
7
+ data.tar.gz: 385cea35eb5451eb138557b3ec3312834fc4826449802f16f7f40531922ca38dc9fdd55c829fcdcc819820b7196cd10a26095ae65b5f252fc3c830d9eb380fdd
@@ -1,33 +1,107 @@
1
- use magnus::{define_module, function, prelude::*, Error, RArray, RString, Value};
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(arg: Value) -> Result<RString, Error> {
5
- let mut class_strings = Vec::new();
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::type_error(),
20
- "Expected String or Array of Strings as argument",
10
+ magnus::exception::arg_error(),
11
+ "wrong number of arguments (expected 1 or 2)",
21
12
  ));
22
13
  }
23
14
 
24
- let merged = tw_merge(class_strings.join(" "));
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
- module.define_singleton_method("merge", function!(merge_tailwind_classes, 1))?;
104
+ // -1 = variable arity (positional + kw-hash)
105
+ module.define_singleton_method("merge", function!(merge_tailwind_classes, -1))?;
32
106
  Ok(())
33
107
  }
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module TailMerge
4
- VERSION = "0.1.0"
4
+ VERSION = "0.2.0"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tail_merge
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Achilleas Buisman