css_inline 0.16.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.16.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.16"
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,49 +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<String>,
56
- Option<bool>,
57
- Option<Obj<StylesheetCache>>,
58
- Option<String>,
59
- Option<usize>,
60
- ),
61
- (),
62
- >(
63
- args.keywords,
64
- &[],
65
- &[
66
- "inline_style_tags",
67
- "keep_style_tags",
68
- "keep_link_tags",
69
- "base_url",
70
- "load_remote_stylesheets",
71
- "cache",
72
- "extra_css",
73
- "preallocate_node_capacity",
74
- ],
75
- )?;
76
- let kwargs = kwargs.optional;
97
+ let kwargs: Options = Options::try_convert(args.keywords.as_value())?;
77
98
  Ok(rust_inline::InlineOptions {
78
- inline_style_tags: kwargs.0.unwrap_or(true),
79
- keep_style_tags: kwargs.1.unwrap_or(false),
80
- keep_link_tags: kwargs.2.unwrap_or(false),
81
- base_url: parse_url(kwargs.3)?,
82
- load_remote_stylesheets: kwargs.4.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),
83
106
  cache: kwargs
84
- .5
107
+ .cache
85
108
  .map(|cache| Mutex::new(rust_inline::StylesheetCache::new(cache.size))),
86
- extra_css: kwargs.6.map(Cow::Owned),
87
- preallocate_node_capacity: kwargs.7.unwrap_or(32),
109
+ extra_css: kwargs.extra_css.map(Cow::Owned),
110
+ preallocate_node_capacity: kwargs.preallocate_node_capacity.unwrap_or(32),
88
111
  resolver: Arc::new(rust_inline::DefaultStylesheetResolver),
89
112
  })
90
113
  }
@@ -98,8 +121,9 @@ struct StylesheetCache {
98
121
  impl StylesheetCache {
99
122
  fn new(args: &[Value]) -> RubyResult<StylesheetCache> {
100
123
  fn error() -> magnus::Error {
124
+ let ruby = Ruby::get().expect("Always called from a Ruby thread");
101
125
  magnus::Error::new(
102
- magnus::exception::arg_error(),
126
+ ruby.exception_arg_error(),
103
127
  "Cache size must be an integer greater than zero",
104
128
  )
105
129
  }
@@ -121,19 +145,19 @@ struct InlineErrorWrapper(rust_inline::InlineError);
121
145
 
122
146
  impl From<InlineErrorWrapper> for magnus::Error {
123
147
  fn from(error: InlineErrorWrapper) -> Self {
148
+ let ruby = Ruby::get().expect("Always called from a Ruby thread");
124
149
  match error.0 {
125
150
  rust_inline::InlineError::IO(error) => {
126
- 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}"))
127
155
  }
128
- rust_inline::InlineError::Network { error, location } => magnus::Error::new(
129
- magnus::exception::arg_error(),
130
- format!("{error}: {location}"),
131
- ),
132
156
  rust_inline::InlineError::ParseError(message) => {
133
- magnus::Error::new(magnus::exception::arg_error(), message.to_string())
157
+ magnus::Error::new(ruby.exception_arg_error(), message.to_string())
134
158
  }
135
159
  rust_inline::InlineError::MissingStyleSheet { .. } => {
136
- magnus::Error::new(magnus::exception::arg_error(), error.0.to_string())
160
+ magnus::Error::new(ruby.exception_arg_error(), error.0.to_string())
137
161
  }
138
162
  }
139
163
  }
@@ -146,8 +170,9 @@ struct UrlError {
146
170
 
147
171
  impl From<UrlError> for magnus::Error {
148
172
  fn from(error: UrlError) -> magnus::Error {
173
+ let ruby = Ruby::get().expect("Always called from a Ruby thread");
149
174
  magnus::Error::new(
150
- magnus::exception::arg_error(),
175
+ ruby.exception_arg_error(),
151
176
  format!("{}: {}", error.error, error.url),
152
177
  )
153
178
  }
@@ -253,8 +278,8 @@ fn inline_many_fragments_impl(
253
278
  }
254
279
 
255
280
  #[magnus::init(name = "css_inline")]
256
- fn init() -> RubyResult<()> {
257
- let module = define_module("CSSInline")?;
281
+ fn init(ruby: &Ruby) -> RubyResult<()> {
282
+ let module = ruby.define_module("CSSInline")?;
258
283
 
259
284
  module.define_module_function("inline", function!(inline, -1))?;
260
285
  module.define_module_function("inline_fragment", function!(inline_fragment, -1))?;
@@ -264,7 +289,7 @@ fn init() -> RubyResult<()> {
264
289
  function!(inline_many_fragments, -1),
265
290
  )?;
266
291
 
267
- let class = module.define_class("CSSInliner", class::object())?;
292
+ let class = module.define_class("CSSInliner", ruby.class_object())?;
268
293
  class.define_singleton_method("new", function!(CSSInliner::new, -1))?;
269
294
  class.define_method("inline", method!(CSSInliner::inline, 1))?;
270
295
  class.define_method("inline_fragment", method!(CSSInliner::inline_fragment, 2))?;
@@ -274,7 +299,7 @@ fn init() -> RubyResult<()> {
274
299
  method!(CSSInliner::inline_many_fragments, 2),
275
300
  )?;
276
301
 
277
- let class = module.define_class("StylesheetCache", class::object())?;
302
+ let class = module.define_class("StylesheetCache", ruby.class_object())?;
278
303
  class.define_singleton_method("new", function!(StylesheetCache::new, -1))?;
279
304
  Ok(())
280
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.16.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-16 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