css_inline 0.17.0 → 0.18.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.
@@ -1,6 +1,6 @@
1
1
  [package]
2
- name = "css-inline"
3
- version = "0.17.0"
2
+ name = "css-inline-ruby"
3
+ version = "0.18.0"
4
4
  authors = ["Dmitry Dygalo <dmitry@dygalo.dev>"]
5
5
  edition = "2021"
6
6
  readme = "README.rdoc"
@@ -9,17 +9,17 @@ repository = "https://github.com/Stranger6667/css-inline"
9
9
  keywords = ["css", "html", "email", "stylesheet", "inlining"]
10
10
  categories = ["web-programming"]
11
11
  license = "MIT"
12
- rust-version = "1.82"
12
+ rust-version = "1.83"
13
13
 
14
14
  [lib]
15
15
  name = "css_inline"
16
16
  crate-type = ["cdylib"]
17
17
 
18
18
  [dependencies]
19
- magnus = "0.7"
19
+ magnus = "0.8"
20
20
  rayon = "1"
21
21
 
22
22
  [dependencies.css-inline]
23
- version = "0.17"
23
+ version = "0.18.0"
24
24
  default-features = false
25
25
  features = ["http", "file", "stylesheet-cache"]
@@ -27,11 +27,11 @@
27
27
  )]
28
28
  use css_inline as rust_inline;
29
29
  use magnus::{
30
- class, define_module, function, method,
30
+ function, method,
31
31
  prelude::*,
32
32
  scan_args::{get_kwargs, scan_args, Args},
33
33
  typed_data::Obj,
34
- DataTypeFunctions, RHash, TypedData, Value,
34
+ DataTypeFunctions, RHash, Ruby, TryConvert, TypedData, Value,
35
35
  };
36
36
  use rayon::prelude::*;
37
37
  use std::{
@@ -42,52 +42,72 @@ use std::{
42
42
 
43
43
  type RubyResult<T> = Result<T, magnus::Error>;
44
44
 
45
+ #[allow(clippy::struct_excessive_bools)]
46
+ struct Options {
47
+ /// Whether to inline CSS from "style" tags.
48
+ ///
49
+ /// Sometimes HTML may include a lot of boilerplate styles, that are not applicable in every
50
+ /// scenario, and it is useful to ignore them and use `extra_css` instead.
51
+ inline_style_tags: Option<bool>,
52
+ /// Keep "style" tags after inlining.
53
+ keep_style_tags: Option<bool>,
54
+ /// Keep "link" tags after inlining.
55
+ keep_link_tags: Option<bool>,
56
+ /// Keep "at-rules" after inlining.
57
+ keep_at_rules: Option<bool>,
58
+ /// Remove trailing semicolons and spaces between properties and values.
59
+ minify_css: Option<bool>,
60
+ /// Used for loading external stylesheets via relative URLs.
61
+ base_url: Option<String>,
62
+ /// Whether remote stylesheets should be loaded or not.
63
+ load_remote_stylesheets: Option<bool>,
64
+ /// An LRU Cache for external stylesheets.
65
+ cache: Option<Obj<StylesheetCache>>,
66
+ /// Additional CSS to inline.
67
+ extra_css: Option<String>,
68
+ /// Pre-allocate capacity for HTML nodes during parsing.
69
+ /// It can improve performance when you have an estimate of the number of nodes in your HTML document.
70
+ preallocate_node_capacity: Option<usize>,
71
+ }
72
+
73
+ impl TryConvert for Options {
74
+ fn try_convert(v: Value) -> Result<Self, magnus::Error> {
75
+ let h = RHash::try_convert(v)?;
76
+ let ruby = Ruby::get_with(v);
77
+ Ok(Self {
78
+ inline_style_tags: h.aref::<_, Option<bool>>(ruby.to_symbol("inline_style_tags"))?,
79
+ keep_style_tags: h.aref::<_, Option<bool>>(ruby.to_symbol("keep_style_tags"))?,
80
+ keep_link_tags: h.aref::<_, Option<bool>>(ruby.to_symbol("keep_link_tags"))?,
81
+ keep_at_rules: h.aref::<_, Option<bool>>(ruby.to_symbol("keep_at_rules"))?,
82
+ minify_css: h.aref::<_, Option<bool>>(ruby.to_symbol("minify_css"))?,
83
+ base_url: h.aref::<_, Option<String>>(ruby.to_symbol("base_url"))?,
84
+ load_remote_stylesheets: h
85
+ .aref::<_, Option<bool>>(ruby.to_symbol("load_remote_stylesheets"))?,
86
+ cache: h.aref::<_, Option<Obj<StylesheetCache>>>(ruby.to_symbol("cache"))?,
87
+ extra_css: h.aref::<_, Option<String>>(ruby.to_symbol("extra_css"))?,
88
+ preallocate_node_capacity: h
89
+ .aref::<_, Option<usize>>(ruby.to_symbol("preallocate_node_capacity"))?,
90
+ })
91
+ }
92
+ }
93
+
45
94
  fn parse_options<Req>(
46
95
  args: &Args<Req, (), (), (), RHash, ()>,
47
96
  ) -> RubyResult<rust_inline::InlineOptions<'static>> {
48
- let kwargs = get_kwargs::<
49
- _,
50
- (),
51
- (
52
- Option<bool>,
53
- Option<bool>,
54
- Option<bool>,
55
- Option<bool>,
56
- Option<String>,
57
- Option<bool>,
58
- Option<Obj<StylesheetCache>>,
59
- Option<String>,
60
- Option<usize>,
61
- ),
62
- (),
63
- >(
64
- args.keywords,
65
- &[],
66
- &[
67
- "inline_style_tags",
68
- "keep_style_tags",
69
- "keep_link_tags",
70
- "keep_at_rules",
71
- "base_url",
72
- "load_remote_stylesheets",
73
- "cache",
74
- "extra_css",
75
- "preallocate_node_capacity",
76
- ],
77
- )?;
78
- let kwargs = kwargs.optional;
97
+ let kwargs: Options = Options::try_convert(args.keywords.as_value())?;
79
98
  Ok(rust_inline::InlineOptions {
80
- inline_style_tags: kwargs.0.unwrap_or(true),
81
- keep_style_tags: kwargs.1.unwrap_or(false),
82
- keep_link_tags: kwargs.2.unwrap_or(false),
83
- keep_at_rules: kwargs.3.unwrap_or(false),
84
- base_url: parse_url(kwargs.4)?,
85
- load_remote_stylesheets: kwargs.5.unwrap_or(true),
99
+ inline_style_tags: kwargs.inline_style_tags.unwrap_or(true),
100
+ keep_style_tags: kwargs.keep_style_tags.unwrap_or(false),
101
+ keep_link_tags: kwargs.keep_link_tags.unwrap_or(false),
102
+ keep_at_rules: kwargs.keep_at_rules.unwrap_or(false),
103
+ minify_css: kwargs.minify_css.unwrap_or(false),
104
+ base_url: parse_url(kwargs.base_url)?,
105
+ load_remote_stylesheets: kwargs.load_remote_stylesheets.unwrap_or(true),
86
106
  cache: kwargs
87
- .6
107
+ .cache
88
108
  .map(|cache| Mutex::new(rust_inline::StylesheetCache::new(cache.size))),
89
- extra_css: kwargs.7.map(Cow::Owned),
90
- preallocate_node_capacity: kwargs.8.unwrap_or(32),
109
+ extra_css: kwargs.extra_css.map(Cow::Owned),
110
+ preallocate_node_capacity: kwargs.preallocate_node_capacity.unwrap_or(32),
91
111
  resolver: Arc::new(rust_inline::DefaultStylesheetResolver),
92
112
  })
93
113
  }
@@ -101,8 +121,9 @@ struct StylesheetCache {
101
121
  impl StylesheetCache {
102
122
  fn new(args: &[Value]) -> RubyResult<StylesheetCache> {
103
123
  fn error() -> magnus::Error {
124
+ let ruby = Ruby::get().expect("Always called from a Ruby thread");
104
125
  magnus::Error::new(
105
- magnus::exception::arg_error(),
126
+ ruby.exception_arg_error(),
106
127
  "Cache size must be an integer greater than zero",
107
128
  )
108
129
  }
@@ -124,19 +145,19 @@ struct InlineErrorWrapper(rust_inline::InlineError);
124
145
 
125
146
  impl From<InlineErrorWrapper> for magnus::Error {
126
147
  fn from(error: InlineErrorWrapper) -> Self {
148
+ let ruby = Ruby::get().expect("Always called from a Ruby thread");
127
149
  match error.0 {
128
150
  rust_inline::InlineError::IO(error) => {
129
- magnus::Error::new(magnus::exception::arg_error(), error.to_string())
151
+ magnus::Error::new(ruby.exception_arg_error(), error.to_string())
152
+ }
153
+ rust_inline::InlineError::Network { error, location } => {
154
+ magnus::Error::new(ruby.exception_arg_error(), format!("{error}: {location}"))
130
155
  }
131
- rust_inline::InlineError::Network { error, location } => magnus::Error::new(
132
- magnus::exception::arg_error(),
133
- format!("{error}: {location}"),
134
- ),
135
156
  rust_inline::InlineError::ParseError(message) => {
136
- magnus::Error::new(magnus::exception::arg_error(), message.to_string())
157
+ magnus::Error::new(ruby.exception_arg_error(), message.to_string())
137
158
  }
138
159
  rust_inline::InlineError::MissingStyleSheet { .. } => {
139
- magnus::Error::new(magnus::exception::arg_error(), error.0.to_string())
160
+ magnus::Error::new(ruby.exception_arg_error(), error.0.to_string())
140
161
  }
141
162
  }
142
163
  }
@@ -149,8 +170,9 @@ struct UrlError {
149
170
 
150
171
  impl From<UrlError> for magnus::Error {
151
172
  fn from(error: UrlError) -> magnus::Error {
173
+ let ruby = Ruby::get().expect("Always called from a Ruby thread");
152
174
  magnus::Error::new(
153
- magnus::exception::arg_error(),
175
+ ruby.exception_arg_error(),
154
176
  format!("{}: {}", error.error, error.url),
155
177
  )
156
178
  }
@@ -256,8 +278,8 @@ fn inline_many_fragments_impl(
256
278
  }
257
279
 
258
280
  #[magnus::init(name = "css_inline")]
259
- fn init() -> RubyResult<()> {
260
- let module = define_module("CSSInline")?;
281
+ fn init(ruby: &Ruby) -> RubyResult<()> {
282
+ let module = ruby.define_module("CSSInline")?;
261
283
 
262
284
  module.define_module_function("inline", function!(inline, -1))?;
263
285
  module.define_module_function("inline_fragment", function!(inline_fragment, -1))?;
@@ -267,7 +289,7 @@ fn init() -> RubyResult<()> {
267
289
  function!(inline_many_fragments, -1),
268
290
  )?;
269
291
 
270
- let class = module.define_class("CSSInliner", class::object())?;
292
+ let class = module.define_class("CSSInliner", ruby.class_object())?;
271
293
  class.define_singleton_method("new", function!(CSSInliner::new, -1))?;
272
294
  class.define_method("inline", method!(CSSInliner::inline, 1))?;
273
295
  class.define_method("inline_fragment", method!(CSSInliner::inline_fragment, 2))?;
@@ -277,7 +299,7 @@ fn init() -> RubyResult<()> {
277
299
  method!(CSSInliner::inline_many_fragments, 2),
278
300
  )?;
279
301
 
280
- let class = module.define_class("StylesheetCache", class::object())?;
302
+ let class = module.define_class("StylesheetCache", ruby.class_object())?;
281
303
  class.define_singleton_method("new", function!(StylesheetCache::new, -1))?;
282
304
  Ok(())
283
305
  }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: css_inline
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.17.0
4
+ version: 0.18.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dmitry Dygalo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-07-26 00:00:00.000000000 Z
11
+ date: 2025-11-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rb_sys
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  - !ruby/object:Gem::Version
142
142
  version: 3.3.26
143
143
  requirements:
144
- - Rust >= 1.82
144
+ - Rust >= 1.83
145
145
  rubygems_version: 3.4.19
146
146
  signing_key:
147
147
  specification_version: 4