Skip to content

Commit 1f63b36

Browse files
committed
feat: Non-blocking stylesheet resolving
1 parent a52171c commit 1f63b36

File tree

21 files changed

+666
-474
lines changed

21 files changed

+666
-474
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
### Added
66

77
- A way to customize resolving remote stylesheets.
8+
- Non-blocking stylesheet resolving by default.
89

910
### Changed
1011

README.md

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,21 @@ const HTML: &str = r#"<html>
7070
</body>
7171
</html>"#;
7272

73+
#[tokio::main]
74+
async fn main() -> css_inline::Result<()> {
75+
let inlined = css_inline::inline(HTML).await?;
76+
// Do something with inlined HTML, e.g. send an email
77+
Ok(())
78+
}
79+
```
80+
81+
There is also a "blocking" API for inlining:
82+
83+
```rust
84+
const HTML: &str = "...";
85+
7386
fn main() -> css_inline::Result<()> {
74-
let inlined = css_inline::inline(HTML)?;
87+
let inlined = css_inline::blocking::inline(HTML)?;
7588
// Do something with inlined HTML, e.g. send an email
7689
Ok(())
7790
}
@@ -84,11 +97,12 @@ fn main() -> css_inline::Result<()> {
8497
```rust
8598
const HTML: &str = "...";
8699

87-
fn main() -> css_inline::Result<()> {
100+
#[tokio::main]
101+
async fn main() -> css_inline::Result<()> {
88102
let inliner = css_inline::CSSInliner::options()
89103
.load_remote_stylesheets(false)
90104
.build();
91-
let inlined = inliner.inline(HTML)?;
105+
let inlined = inliner.inline(HTML).await?;
92106
// Do something with inlined HTML, e.g. send an email
93107
Ok(())
94108
}
@@ -131,12 +145,28 @@ If you'd like to load stylesheets from your filesystem, use the `file://` scheme
131145
```rust
132146
const HTML: &str = "...";
133147

134-
fn main() -> css_inline::Result<()> {
148+
#[tokio::main]
149+
async fn main() -> css_inline::Result<()> {
135150
let base_url = css_inline::Url::parse("file://styles/email/").expect("Invalid URL");
136151
let inliner = css_inline::CSSInliner::options()
137152
.base_url(Some(base_url))
138153
.build();
139-
let inlined = inliner.inline(HTML);
154+
let inlined = inliner.inline(HTML).await?;
155+
// Do something with inlined HTML, e.g. send an email
156+
Ok(())
157+
}
158+
```
159+
160+
The blocking version is available as well:
161+
162+
```rust
163+
const HTML: &str = "...";
164+
165+
fn main() -> css_inline::Result<()> {
166+
let inliner = css_inline::blocking::CSSInliner::options()
167+
.load_remote_stylesheets(false)
168+
.build();
169+
let inlined = inliner.inline(HTML)?;
140170
// Do something with inlined HTML, e.g. send an email
141171
Ok(())
142172
}
@@ -149,7 +179,7 @@ For resolving remote stylesheets it is possible to implement a custom resolver:
149179
pub struct CustomStylesheetResolver;
150180

151181
impl css_inline::StylesheetResolver for CustomStylesheetResolver {
152-
fn retrieve(&self, location: &str) -> css_inline::Result<String> {
182+
fn retrieve_blocking(&self, location: &str) -> css_inline::Result<String> {
153183
Err(self.unsupported("External stylesheets are not supported"))
154184
}
155185
}

bindings/c/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,4 @@ cbindgen = "0.26"
1818
path = "../../css-inline"
1919
version = "*"
2020
default-features = false
21-
features = ["http", "file"]
21+
features = ["http-blocking", "file"]

bindings/c/src/lib.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
1-
use css_inline::{CSSInliner, DefaultStylesheetResolver, InlineError, InlineOptions, Url};
1+
use css_inline::{
2+
blocking::{CSSInliner, InlineOptions},
3+
DefaultStylesheetResolver, InlineError, Url,
4+
};
25
use libc::{c_char, size_t};
36
use std::{borrow::Cow, cmp, ffi::CStr, io::Write, ptr, sync::Arc};
47

bindings/javascript/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ serde = { version = "1", features = ["derive"], default-features = false }
3232
path = "../../css-inline"
3333
version = "*"
3434
default-features = false
35-
features = ["http", "file"]
35+
features = ["http-blocking", "file"]
3636

3737
[target.'cfg(target_arch = "wasm32")'.dependencies.css-inline]
3838
path = "../../css-inline"

bindings/javascript/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,6 @@ export function inline(html: string, options?: InlineOptions): string;
6060
export function version(): string;"#;
6161

6262
fn inline_inner(html: String, options: Options) -> std::result::Result<String, errors::JsError> {
63-
let inliner = css_inline::CSSInliner::new(options.try_into()?);
63+
let inliner = css_inline::blocking::CSSInliner::new(options.try_into()?);
6464
Ok(inliner.inline(&html).map_err(errors::InlineError)?)
6565
}

bindings/javascript/src/options.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -42,11 +42,11 @@ pub struct Options {
4242
pub preallocate_node_capacity: Option<u32>,
4343
}
4444

45-
impl TryFrom<Options> for css_inline::InlineOptions<'_> {
45+
impl TryFrom<Options> for css_inline::blocking::InlineOptions<'_> {
4646
type Error = JsError;
4747

4848
fn try_from(value: Options) -> std::result::Result<Self, Self::Error> {
49-
Ok(css_inline::InlineOptions {
49+
Ok(css_inline::blocking::InlineOptions {
5050
inline_style_tags: value.inline_style_tags.unwrap_or(true),
5151
keep_style_tags: value.keep_style_tags.unwrap_or(false),
5252
keep_link_tags: value.keep_link_tags.unwrap_or(false),

bindings/python/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ url = "2"
2323
path = "../../css-inline"
2424
version = "*"
2525
default-features = false
26-
features = ["http", "file"]
26+
features = ["http-blocking", "file"]
2727

2828
[profile.release]
2929
codegen-units = 1

bindings/python/src/lib.rs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ fn parse_url(url: Option<String>) -> PyResult<Option<rust_inline::Url>> {
7474
/// Customizable CSS inliner.
7575
#[pyclass]
7676
struct CSSInliner {
77-
inner: rust_inline::CSSInliner<'static>,
77+
inner: rust_inline::blocking::CSSInliner<'static>,
7878
}
7979

8080
macro_rules! inliner {
8181
($inline_style_tags:expr, $keep_style_tags:expr, $keep_link_tags:expr, $base_url:expr, $load_remote_stylesheets:expr, $extra_css:expr, $preallocate_node_capacity:expr) => {{
82-
let options = rust_inline::InlineOptions {
82+
rust_inline::blocking::InlineOptions {
8383
inline_style_tags: $inline_style_tags.unwrap_or(true),
8484
keep_style_tags: $keep_style_tags.unwrap_or(false),
8585
keep_link_tags: $keep_link_tags.unwrap_or(false),
@@ -88,8 +88,7 @@ macro_rules! inliner {
8888
extra_css: $extra_css.map(Into::into),
8989
preallocate_node_capacity: $preallocate_node_capacity.unwrap_or(32),
9090
resolver: std::sync::Arc::new(rust_inline::DefaultStylesheetResolver),
91-
};
92-
rust_inline::CSSInliner::new(options)
91+
}.build()
9392
}};
9493
}
9594

@@ -198,7 +197,7 @@ fn inline_many(
198197
}
199198

200199
fn inline_many_impl(
201-
inliner: &rust_inline::CSSInliner<'_>,
200+
inliner: &rust_inline::blocking::CSSInliner<'_>,
202201
htmls: &PyList,
203202
) -> PyResult<Vec<String>> {
204203
// Extract strings from the list. It will fail if there is any non-string value

bindings/ruby/ext/css_inline/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,4 @@ rayon = "1"
2323
path = "../../../../css-inline"
2424
version = "*"
2525
default-features = false
26-
features = ["http", "file"]
26+
features = ["http-blocking", "file"]

0 commit comments

Comments
 (0)