Skip to content

Commit e44643b

Browse files
committed
refactor: refactored into multiple modules, export builders
Signed-off-by: Martin <martin@hotmail.com.br>
1 parent 91d35eb commit e44643b

File tree

5 files changed

+162
-99
lines changed

5 files changed

+162
-99
lines changed

README.md

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,19 @@
11
# actix-prerender
22

3-
A very simple middleware that sends requests which comes from common crawler
4-
user-agents to be pre-rendered via "prerender".
3+
A simple middleware that sends HTTP requests from known crawlers user-agents to
4+
be rendered by an external prerender service URL or
5+
[prerender.io](https://prerender.io "Prerender.io website").
56

6-
It accepts the external service provided by `prerender.io`, or a custom external
7-
`prerender_service_url`.
7+
## Usage
8+
9+
```rust
10+
```
11+
12+
13+
## Installation
14+
15+
Add this into your `Cargo.toml`
16+
17+
```toml
18+
actix-prerender = { git = "https://github.com/saskenuba/actix-prerender" }
19+
```

src/builder.rs

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
use crate::middleware::Inner;
2+
use crate::{middleware, PrerenderError, PrerenderMiddleware};
3+
use actix_service::{Service, Transform};
4+
use actix_utils::future;
5+
use actix_utils::future::Ready;
6+
use actix_web::body::BoxBody;
7+
use actix_web::dev::{ServiceRequest, ServiceResponse};
8+
use actix_web::Error;
9+
use reqwest::Client;
10+
use std::rc::Rc;
11+
use url::Url;
12+
13+
/// Builder for Prerender middleware.
14+
///
15+
/// To construct a Prerender middleware, call [`Prerender::build()`] to create a builder.
16+
/// Then you can choose between `self..use_prerender_io`
17+
///
18+
/// # Errors
19+
///
20+
/// TODO
21+
///
22+
/// # Prerender.io example
23+
/// ```
24+
/// use actix_prerender::Prerender;
25+
/// use actix_web::http::header;
26+
///
27+
/// let token = "prerender service token".to_string();
28+
/// let prerender = Prerender::build().use_prerender_io(token);
29+
///
30+
/// // `prerender` can now be used in `App::wrap`.
31+
/// ```
32+
/// # Custom service URL example
33+
/// ```
34+
/// use actix_prerender::Prerender;
35+
/// use actix_web::http::header;
36+
///
37+
/// let token = "prerender service token".to_string();
38+
/// let prerender = Prerender::build().use_custom_prerender_url("https://localhost:5001", token);
39+
///
40+
/// // `prerender` can now be used in `App::wrap`.
41+
/// ```
42+
#[derive(Debug, Clone)]
43+
pub struct Prerender {
44+
inner: Rc<Inner>,
45+
}
46+
47+
#[derive(Debug, Clone)]
48+
pub struct PrerenderBuilder {}
49+
50+
impl PrerenderBuilder {
51+
pub fn use_prerender_io(self, token: String) -> Prerender {
52+
let inner = Inner {
53+
prerender_service_url: middleware::prerender_url(),
54+
inner_client: Client::default(),
55+
prerender_token: token,
56+
};
57+
58+
Prerender { inner: Rc::new(inner) }
59+
}
60+
61+
pub fn use_custom_prerender_url(
62+
self,
63+
prerender_service_url: &str,
64+
token: String,
65+
) -> Result<Prerender, PrerenderError> {
66+
let prerender_service_url = Url::parse(prerender_service_url).map_err(|_| PrerenderError::InvalidUrl)?;
67+
68+
let inner = Inner {
69+
prerender_service_url,
70+
inner_client: Client::default(),
71+
prerender_token: token,
72+
};
73+
74+
Ok(Prerender { inner: Rc::new(inner) })
75+
}
76+
}
77+
78+
impl Prerender {
79+
pub const fn build() -> PrerenderBuilder {
80+
PrerenderBuilder {}
81+
}
82+
}
83+
84+
impl<S> Transform<S, ServiceRequest> for Prerender
85+
where
86+
S: Service<ServiceRequest, Response = ServiceResponse, Error = Error>,
87+
S::Future: 'static,
88+
{
89+
type Response = ServiceResponse<BoxBody>;
90+
type Error = Error;
91+
type Transform = PrerenderMiddleware<S>;
92+
type InitError = ();
93+
type Future = Ready<Result<Self::Transform, Self::InitError>>;
94+
95+
fn new_transform(&self, service: S) -> Self::Future {
96+
future::ok(PrerenderMiddleware {
97+
service,
98+
inner: Rc::clone(&self.inner),
99+
})
100+
}
101+
}
File renamed without changes.

src/lib.rs

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,29 @@
1-
//! Prerender for Actix Web
1+
//! # Example
2+
//! ```no_run
3+
//! use actix_prerender::Prerender;
4+
//! use actix_web::{get, http, web, App, HttpRequest, HttpResponse, HttpServer};
5+
//!
6+
//! #[get("/index.html")]
7+
//! async fn index(req: HttpRequest) -> &'static str {
8+
//! "<p>Hello World!</p>"
9+
//! }
10+
//!
11+
//! #[actix_web::main]
12+
//! async fn main() -> std::io::Result<()> {
13+
//! HttpServer::new(|| {
14+
//! let prerender = Prerender::build().use_prerender_io("service_token".to_string());
15+
//!
16+
//! App::new()
17+
//! .wrap(prerender)
18+
//! .service(index)
19+
//! })
20+
//! .bind(("127.0.0.1", 8080))?
21+
//! .run()
22+
//! .await;
23+
//!
24+
//! Ok(())
25+
//! }
26+
//! ```
227
328
#![forbid(unsafe_code)]
429
#![deny(nonstandard_style)]
@@ -9,23 +34,11 @@
934

1035
use consts::{IGNORED_EXTENSIONS, USER_AGENTS};
1136

37+
mod builder;
1238
mod consts;
13-
pub mod errors;
14-
pub mod middleware;
39+
mod error;
40+
mod middleware;
1541

16-
// impl<S, B> Service<ServiceRequest> for PrerenderMiddleWare
17-
// where
18-
// S: Service<ServiceRequest, Response = ServiceResponse<B>, Error = Error>,
19-
// S::Future: 'static,
20-
// B: MessageBody + 'static,
21-
// {
22-
// type Response = ServiceResponse<EitherBody<B>>;
23-
// type Error = Error;
24-
// type Future = LocalBoxFuture<'static, Result<ServiceResponse<EitherBody<B>>, Error>>;
25-
//
26-
// actix_service::forward_ready!(service);
27-
//
28-
// fn call(&self, req: ServiceRequest) -> Self::Future {
29-
// todo!()
30-
// }
31-
// }
42+
pub use builder::Prerender;
43+
pub use error::PrerenderError;
44+
pub use middleware::PrerenderMiddleware;

src/middleware.rs

Lines changed: 13 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
use actix_service::{Service, Transform};
2-
use actix_utils::future;
3-
use actix_utils::future::Ready;
1+
use std::rc::Rc;
2+
3+
use actix_service::Service;
44
use actix_web::body::BoxBody;
55
use actix_web::dev::{ServiceRequest, ServiceResponse};
66
use actix_web::http::header::HeaderMap;
@@ -10,64 +10,19 @@ use actix_web::{Error, HttpResponse};
1010
use futures_util::future::LocalBoxFuture;
1111
use futures_util::TryFutureExt;
1212
use reqwest::Client;
13-
use std::rc::Rc;
1413
use url::Url;
1514

16-
use crate::errors::PrerenderError;
15+
use crate::error::PrerenderError;
1716
use crate::{IGNORED_EXTENSIONS, USER_AGENTS};
1817

19-
#[derive(Debug, Clone)]
20-
pub struct Prerender {
21-
inner: Rc<Inner>,
22-
}
23-
2418
#[derive(Debug, Clone)]
2519
pub struct Inner {
26-
prerender_service_url: Url,
27-
inner_client: Client,
28-
prerender_token: String,
20+
pub(crate) prerender_service_url: Url,
21+
pub(crate) inner_client: Client,
22+
pub(crate) prerender_token: String,
2923
}
3024

31-
impl Prerender {}
32-
33-
#[derive(Debug, Clone)]
34-
pub struct PrerenderBuilder {}
35-
36-
impl PrerenderBuilder {
37-
pub fn use_prerender_io(self, token: String) -> Prerender {
38-
let inner = Inner {
39-
prerender_service_url: prerender_url(),
40-
inner_client: Client::default(),
41-
prerender_token: token,
42-
};
43-
44-
Prerender { inner: Rc::new(inner) }
45-
}
46-
47-
pub fn use_custom_prerender_url(
48-
self,
49-
prerender_service_url: &str,
50-
token: String,
51-
) -> Result<Prerender, PrerenderError> {
52-
let prerender_service_url = Url::parse(prerender_service_url).map_err(|_| PrerenderError::InvalidUrl)?;
53-
54-
let inner = Inner {
55-
prerender_service_url,
56-
inner_client: Client::default(),
57-
prerender_token: token,
58-
};
59-
60-
Ok(Prerender { inner: Rc::new(inner) })
61-
}
62-
}
63-
64-
impl Prerender {
65-
pub const fn builder() -> PrerenderBuilder {
66-
PrerenderBuilder {}
67-
}
68-
}
69-
70-
fn prerender_url() -> Url {
25+
pub(crate) fn prerender_url() -> Url {
7126
Url::parse("https://service.prerender.io").unwrap()
7227
}
7328

@@ -118,7 +73,7 @@ pub(crate) fn should_prerender(req: &ServiceRequest) -> bool {
11873
#[derive(Debug)]
11974
pub struct PrerenderMiddleware<S> {
12075
pub(crate) service: S,
121-
inner: Rc<Inner>,
76+
pub(crate) inner: Rc<Inner>,
12277
}
12378

12479
impl<S> PrerenderMiddleware<S> {
@@ -190,42 +145,24 @@ where
190145
}
191146
}
192147

193-
impl<S> Transform<S, ServiceRequest> for Prerender
194-
where
195-
S: Service<ServiceRequest, Response = ServiceResponse, Error = Error>,
196-
S::Future: 'static,
197-
{
198-
type Response = ServiceResponse<BoxBody>;
199-
type Error = Error;
200-
type Transform = PrerenderMiddleware<S>;
201-
type InitError = ();
202-
type Future = Ready<Result<Self::Transform, Self::InitError>>;
203-
204-
fn new_transform(&self, service: S) -> Self::Future {
205-
future::ok(PrerenderMiddleware {
206-
service,
207-
inner: Rc::clone(&self.inner),
208-
})
209-
}
210-
}
211-
212148
#[cfg(test)]
213149
mod tests {
214150

151+
use crate::builder::Prerender;
215152
use actix_web::http::header;
216153
use actix_web::middleware::Compat;
217154
use actix_web::test::TestRequest;
218155
use actix_web::App;
219156

220-
use crate::middleware::{prerender_url, should_prerender, Prerender, PrerenderMiddleware};
157+
use crate::middleware::{prerender_url, should_prerender, PrerenderMiddleware};
221158

222159
fn _init_logger() {
223160
let _ = env_logger::builder().is_test(true).try_init();
224161
}
225162

226163
#[actix_web::test]
227164
async fn compat_compat() {
228-
App::new().wrap(Compat::new(Prerender::builder().use_prerender_io("".to_string())));
165+
App::new().wrap(Compat::new(Prerender::build().use_prerender_io("".to_string())));
229166
}
230167

231168
#[actix_web::test]
@@ -283,7 +220,7 @@ mod tests {
283220
}
284221

285222
fn _create_middleware() -> Prerender {
286-
Prerender::builder().use_prerender_io("".to_string())
223+
Prerender::build().use_prerender_io("".to_string())
287224
}
288225

289226
#[actix_web::test]

0 commit comments

Comments
 (0)