Skip to main content

html2pdf_api/
prelude.rs

1//! Convenient imports for common usage patterns.
2//!
3//! This module re-exports the most commonly used types from `html2pdf-api`,
4//! allowing you to quickly get started with a single import.
5//!
6//! # Quick Start
7//!
8//! ```rust,ignore
9//! use html2pdf_api::prelude::*;
10//! ```
11//!
12//! This single line gives you access to all the core types needed to create
13//! and use a browser pool for PDF generation.
14//!
15//! # What's Included
16//!
17//! ## Core Types (Always Available)
18//!
19//! | Type | Description |
20//! |------|-------------|
21//! | [`BrowserPool`] | Main pool for managing browser instances |
22//! | [`BrowserPoolBuilder`] | Builder for creating configured pools |
23//! | [`BrowserPoolConfig`] | Configuration settings for the pool |
24//! | [`BrowserPoolConfigBuilder`] | Builder for creating configurations |
25//! | [`BrowserPoolError`] | Error type for pool operations |
26//! | [`Result`] | Type alias for `Result<T, BrowserPoolError>` |
27//! | [`BrowserHandle`] | RAII handle for checked-out browsers |
28//! | [`PoolStats`] | Real-time pool statistics |
29//! | [`BrowserFactory`] | Trait for browser creation strategies |
30//! | [`ChromeBrowserFactory`] | Default Chrome/Chromium factory |
31//! | [`Healthcheck`] | Trait for browser health checking |
32//! | [`SharedBrowserPool`] | Type alias for `Arc<BrowserPool>` |
33//!
34//! ## Standard Library Re-exports
35//!
36//! For convenience, commonly needed types are re-exported:
37//!
38//! | Type | Description |
39//! |------|-------------|
40//! | [`Arc`] | Thread-safe reference counting |
41//!
42//! ## Feature-Gated Exports
43//!
44//! Additional exports are available with feature flags:
45//!
46//! ### `env-config` Feature
47//!
48//! | Export | Description |
49//! |--------|-------------|
50//! | [`init_browser_pool`] | Initialize pool from environment variables |
51//! | [`from_env`] | Load configuration from environment |
52//! | [`chrome_path_from_env`] | Get Chrome path from `CHROME_PATH` env var |
53//!
54//! ### `actix-integration` Feature
55//!
56//! | Export | Description |
57//! |--------|-------------|
58//! | [`actix`] module | Actix-web handlers and helpers |
59//!
60//! ### `rocket-integration` Feature
61//!
62//! | Export | Description |
63//! |--------|-------------|
64//! | [`rocket`] module | Rocket handlers and helpers |
65//!
66//! ### `axum-integration` Feature
67//!
68//! | Export | Description |
69//! |--------|-------------|
70//! | [`axum`] module | Axum handlers and router |
71//!
72//! ### Any Integration Feature
73//!
74//! When any integration feature is enabled, service types are also available:
75//!
76//! | Type | Description |
77//! |------|-------------|
78//! | [`PdfFromUrlRequest`] | Request parameters for URL-to-PDF |
79//! | [`PdfFromHtmlRequest`] | Request parameters for HTML-to-PDF |
80//! | [`PdfResponse`] | Successful PDF generation result |
81//! | [`PdfServiceError`] | Service-level errors |
82//! | [`ErrorResponse`] | JSON error response format |
83//! | [`PoolStatsResponse`] | Pool statistics response |
84//! | [`HealthResponse`] | Health check response |
85//!
86//! # Usage Examples
87//!
88//! ## Basic Usage
89//!
90//! Create a pool with manual configuration:
91//!
92//! ```rust,ignore
93//! use html2pdf_api::prelude::*;
94//! use std::time::Duration;
95//!
96//! #[tokio::main]
97//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
98//!     // Build configuration
99//!     let config = BrowserPoolConfigBuilder::new()
100//!         .max_pool_size(5)
101//!         .warmup_count(3)
102//!         .browser_ttl(Duration::from_secs(3600))
103//!         .build()?;
104//!
105//!     // Create pool
106//!     let pool = BrowserPool::builder()
107//!         .config(config)
108//!         .factory(Box::new(ChromeBrowserFactory::with_defaults()))
109//!         .build()?;
110//!
111//!     // Warmup for production readiness
112//!     pool.warmup().await?;
113//!
114//!     // Use a browser (automatically returned to pool when dropped)
115//!     {
116//!         let browser = pool.get()?;
117//!         let tab = browser.new_tab()?;
118//!         tab.navigate_to("https://example.com")?;
119//!         tab.wait_until_navigated()?;
120//!         let pdf = tab.print_to_pdf(None)?;
121//!         std::fs::write("output.pdf", pdf)?;
122//!     }
123//!
124//!     // Graceful shutdown
125//!     pool.shutdown();
126//!
127//!     Ok(())
128//! }
129//! ```
130//!
131//! ## Using Environment Configuration
132//!
133//! With the `env-config` feature, initialization is simpler:
134//!
135//! ```rust,ignore
136//! use html2pdf_api::prelude::*;
137//!
138//! #[tokio::main]
139//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
140//!     // Reads BROWSER_POOL_SIZE, BROWSER_TTL_SECONDS, etc.
141//!     let pool = init_browser_pool().await?;
142//!
143//!     // Pool is Arc<BrowserPool>, ready for sharing
144//!     let browser = pool.get()?;
145//!     // ...
146//!
147//!     Ok(())
148//! }
149//! ```
150//!
151//! ## With Actix-web (Pre-built Routes)
152//!
153//! The fastest way to set up a PDF API:
154//!
155//! ```rust,ignore
156//! use actix_web::{App, HttpServer, web};
157//! use html2pdf_api::prelude::*;
158//! use html2pdf_api::integrations::actix::configure_routes;
159//!
160//! #[actix_web::main]
161//! async fn main() -> std::io::Result<()> {
162//!     let pool = init_browser_pool().await
163//!         .expect("Failed to initialize pool");
164//!
165//!     HttpServer::new(move || {
166//!         App::new()
167//!             .app_data(web::Data::new(pool.clone()))
168//!             .configure(configure_routes) // Adds /pdf, /pdf/html, /health, etc.
169//!     })
170//!     .bind("127.0.0.1:8080")?
171//!     .run()
172//!     .await
173//! }
174//! ```
175//!
176//! ## With Actix-web (Custom Handler)
177//!
178//! For more control, use service functions directly:
179//!
180//! ```rust,ignore
181//! use actix_web::{web, HttpResponse, Responder};
182//! use html2pdf_api::prelude::*;
183//! use html2pdf_api::service::{generate_pdf_from_url, PdfFromUrlRequest};
184//!
185//! async fn my_pdf_handler(
186//!     pool: web::Data<SharedBrowserPool>,
187//!     query: web::Query<PdfFromUrlRequest>,
188//! ) -> impl Responder {
189//!     let pool = pool.into_inner();
190//!     let request = query.into_inner();
191//!
192//!     let result = web::block(move || {
193//!         generate_pdf_from_url(&pool, &request)
194//!     }).await;
195//!
196//!     match result {
197//!         Ok(Ok(pdf)) => HttpResponse::Ok()
198//!             .content_type("application/pdf")
199//!             .body(pdf.data),
200//!         Ok(Err(e)) => HttpResponse::BadRequest().body(e.to_string()),
201//!         Err(e) => HttpResponse::InternalServerError().body(e.to_string()),
202//!     }
203//! }
204//! ```
205//!
206//! ## Checking Pool Statistics
207//!
208//! Monitor pool health in your application:
209//!
210//! ```rust,ignore
211//! use html2pdf_api::prelude::*;
212//!
213//! fn log_pool_status(pool: &SharedBrowserPool) {
214//!     let stats = pool.stats();
215//!     println!("Pool Status:");
216//!     println!("  Available: {}", stats.available);
217//!     println!("  Active: {}", stats.active);
218//!     println!("  Total: {}", stats.total);
219//!     
220//!     // Check capacity
221//!     if stats.available == 0 {
222//!         println!("  ⚠️ Warning: No idle browsers available");
223//!     }
224//! }
225//! ```
226//!
227//! ## Error Handling
228//!
229//! Handle pool errors appropriately:
230//!
231//! ```rust,ignore
232//! use html2pdf_api::prelude::*;
233//!
234//! fn generate_pdf(pool: &SharedBrowserPool, url: &str) -> Result<Vec<u8>> {
235//!     let browser = pool.get()?;  // Returns BrowserPoolError
236//!     let tab = browser.new_tab()
237//!         .map_err(|e| BrowserPoolError::BrowserCreation(e.to_string()))?;
238//!
239//!     tab.navigate_to(url)
240//!         .map_err(|e| BrowserPoolError::BrowserCreation(e.to_string()))?;
241//!     tab.wait_until_navigated()
242//!         .map_err(|e| BrowserPoolError::BrowserCreation(e.to_string()))?;
243//!
244//!     let pdf = tab.print_to_pdf(None)
245//!         .map_err(|e| BrowserPoolError::BrowserCreation(e.to_string()))?;
246//!
247//!     Ok(pdf)
248//! }
249//! ```
250//!
251//! # Feature Flag Reference
252//!
253//! | Feature | Adds to Prelude |
254//! |---------|-----------------|
255//! | (none) | Core types only |
256//! | `env-config` | `init_browser_pool`, `from_env`, `chrome_path_from_env` |
257//! | `actix-integration` | `actix` module + service types |
258//! | `rocket-integration` | `rocket` module + service types |
259//! | `axum-integration` | `axum` module + service types |
260//! | `test-utils` | `MockBrowserFactory` (in `factory::mock`) |
261//!
262//! # See Also
263//!
264//! - [`crate::pool`] - Browser pool implementation details
265//! - [`crate::config`] - Configuration options
266//! - [`crate::service`] - Core PDF generation service
267//! - [`crate::integrations`] - Web framework integrations
268
269// ============================================================================
270// Core Types (Always Available)
271// ============================================================================
272
273/// The main browser pool type for managing browser instances.
274///
275/// See [`crate::pool::BrowserPool`] for full documentation.
276pub use crate::pool::BrowserPool;
277
278/// Builder for creating configured [`BrowserPool`] instances.
279///
280/// See [`crate::pool::BrowserPoolBuilder`] for full documentation.
281pub use crate::pool::BrowserPoolBuilder;
282
283/// Configuration settings for the browser pool.
284///
285/// See [`crate::config::BrowserPoolConfig`] for full documentation.
286pub use crate::config::BrowserPoolConfig;
287
288/// Builder for creating [`BrowserPoolConfig`] instances.
289///
290/// See [`crate::config::BrowserPoolConfigBuilder`] for full documentation.
291pub use crate::config::BrowserPoolConfigBuilder;
292
293/// Error type for browser pool operations.
294///
295/// See [`crate::error::BrowserPoolError`] for full documentation.
296pub use crate::error::BrowserPoolError;
297
298/// Result type alias using [`BrowserPoolError`].
299///
300/// Equivalent to `std::result::Result<T, BrowserPoolError>`.
301pub use crate::error::Result;
302
303/// RAII handle for a browser checked out from the pool.
304///
305/// When dropped, the browser is automatically returned to the pool.
306/// See [`crate::handle::BrowserHandle`] for full documentation.
307pub use crate::handle::BrowserHandle;
308
309/// Real-time statistics about the browser pool.
310///
311/// See [`crate::stats::PoolStats`] for full documentation.
312pub use crate::stats::PoolStats;
313
314/// Trait for browser creation strategies.
315///
316/// Implement this trait to customize how browsers are created.
317/// See [`crate::factory::BrowserFactory`] for full documentation.
318pub use crate::factory::BrowserFactory;
319
320/// Default factory for creating Chrome/Chromium browsers.
321///
322/// See [`crate::factory::ChromeBrowserFactory`] for full documentation.
323pub use crate::factory::ChromeBrowserFactory;
324
325/// Trait for browser health checking.
326///
327/// See [`crate::traits::Healthcheck`] for full documentation.
328pub use crate::traits::Healthcheck;
329
330/// Type alias for a shared, thread-safe browser pool.
331///
332/// This is defined as `Arc<BrowserPool>` and is the standard
333/// way to share a pool across threads and async tasks.
334/// No outer `Mutex` is needed — the pool uses fine-grained internal locks.
335///
336/// # Example
337///
338/// ```rust,ignore
339/// use html2pdf_api::prelude::*;
340///
341/// let pool: SharedBrowserPool = BrowserPool::builder()
342///     .factory(Box::new(ChromeBrowserFactory::with_defaults()))
343///     .build()
344///     .unwrap()
345///     .into_shared();
346/// ```
347pub use crate::SharedBrowserPool;
348
349// ============================================================================
350// Standard Library Re-exports
351// ============================================================================
352
353/// Thread-safe reference counting pointer.
354///
355/// Re-exported for convenience when working with [`SharedBrowserPool`].
356///
357/// # Example
358///
359/// ```rust,ignore
360/// use html2pdf_api::prelude::*;
361///
362/// let pool = init_browser_pool().await?;
363/// let pool_clone = Arc::clone(&pool);  // Clone for another thread/task
364/// ```
365pub use std::sync::Arc;
366
367// (Mutex re-export removed — no longer needed for SharedBrowserPool)
368
369// ============================================================================
370// Environment Configuration (env-config feature)
371// ============================================================================
372
373/// Initialize a browser pool from environment variables.
374///
375/// This function reads configuration from environment variables and creates
376/// a ready-to-use shared pool. It's the recommended way to initialize the
377/// pool in production.
378///
379/// # Environment Variables
380///
381/// | Variable | Type | Default | Description |
382/// |----------|------|---------|-------------|
383/// | `BROWSER_POOL_SIZE` | usize | 5 | Maximum browsers in pool |
384/// | `BROWSER_WARMUP_COUNT` | usize | 3 | Browsers to pre-create |
385/// | `BROWSER_TTL_SECONDS` | u64 | 3600 | Browser lifetime |
386/// | `BROWSER_WARMUP_TIMEOUT_SECONDS` | u64 | 60 | Warmup timeout |
387/// | `BROWSER_PING_INTERVAL_SECONDS` | u64 | 15 | Health check interval |
388/// | `BROWSER_MAX_PING_FAILURES` | u32 | 3 | Max failures before removal |
389/// | `CHROME_PATH` | String | auto | Custom Chrome path |
390///
391/// # Example
392///
393/// ```rust,ignore
394/// use html2pdf_api::prelude::*;
395///
396/// #[tokio::main]
397/// async fn main() -> Result<(), Box<dyn std::error::Error>> {
398///     let pool = init_browser_pool().await?;
399///     // Pool is ready to use!
400///     Ok(())
401/// }
402/// ```
403///
404/// # Errors
405///
406/// Returns an error if:
407/// - Environment variables contain invalid values
408/// - Chrome/Chromium cannot be found or launched
409/// - Pool warmup fails
410#[cfg(feature = "env-config")]
411pub use crate::pool::init_browser_pool;
412
413/// Load pool configuration from environment variables.
414///
415/// Use this when you need to customize pool creation but still want
416/// environment-based configuration.
417///
418/// # Example
419///
420/// ```rust,ignore
421/// use html2pdf_api::prelude::*;
422///
423/// let config = from_env()?;
424/// let pool = BrowserPool::builder()
425///     .config(config)
426///     .factory(Box::new(ChromeBrowserFactory::with_defaults()))
427///     .enable_keep_alive(true)  // Custom option
428///     .build()?;
429/// ```
430#[cfg(feature = "env-config")]
431pub use crate::config::env::from_env;
432
433/// Get Chrome path from the `CHROME_PATH` environment variable.
434///
435/// Returns `Some(path)` if the variable is set, `None` otherwise.
436///
437/// # Example
438///
439/// ```rust,ignore
440/// use html2pdf_api::prelude::*;
441///
442/// let factory = match chrome_path_from_env() {
443///     Some(path) => ChromeBrowserFactory::with_path(path),
444///     None => ChromeBrowserFactory::with_defaults(),
445/// };
446/// ```
447#[cfg(feature = "env-config")]
448pub use crate::config::env::chrome_path_from_env;
449
450// ============================================================================
451// Service Types (Any Integration Feature)
452// ============================================================================
453
454/// Request parameters for URL-to-PDF conversion.
455///
456/// See [`crate::service::PdfFromUrlRequest`] for full documentation.
457#[cfg(any(
458    feature = "actix-integration",
459    feature = "rocket-integration",
460    feature = "axum-integration"
461))]
462pub use crate::service::PdfFromUrlRequest;
463
464/// Request parameters for HTML-to-PDF conversion.
465///
466/// See [`crate::service::PdfFromHtmlRequest`] for full documentation.
467#[cfg(any(
468    feature = "actix-integration",
469    feature = "rocket-integration",
470    feature = "axum-integration"
471))]
472pub use crate::service::PdfFromHtmlRequest;
473
474/// Successful PDF generation result.
475///
476/// Contains the PDF binary data and metadata.
477/// See [`crate::service::PdfResponse`] for full documentation.
478#[cfg(any(
479    feature = "actix-integration",
480    feature = "rocket-integration",
481    feature = "axum-integration"
482))]
483pub use crate::service::PdfResponse;
484
485/// Errors that can occur during PDF generation.
486///
487/// Includes HTTP status code mapping for easy response building.
488/// See [`crate::service::PdfServiceError`] for full documentation.
489#[cfg(any(
490    feature = "actix-integration",
491    feature = "rocket-integration",
492    feature = "axum-integration"
493))]
494pub use crate::service::PdfServiceError;
495
496/// JSON error response format.
497///
498/// See [`crate::service::ErrorResponse`] for full documentation.
499#[cfg(any(
500    feature = "actix-integration",
501    feature = "rocket-integration",
502    feature = "axum-integration"
503))]
504pub use crate::service::ErrorResponse;
505
506/// Pool statistics response for API endpoints.
507///
508/// See [`crate::service::PoolStatsResponse`] for full documentation.
509#[cfg(any(
510    feature = "actix-integration",
511    feature = "rocket-integration",
512    feature = "axum-integration"
513))]
514pub use crate::service::PoolStatsResponse;
515
516/// Health check response for API endpoints.
517///
518/// See [`crate::service::HealthResponse`] for full documentation.
519#[cfg(any(
520    feature = "actix-integration",
521    feature = "rocket-integration",
522    feature = "axum-integration"
523))]
524pub use crate::service::HealthResponse;
525
526// ============================================================================
527// Framework-Specific Modules
528// ============================================================================
529
530/// Actix-web integration module.
531///
532/// Provides pre-built handlers and helpers for Actix-web 4.x.
533///
534/// # Quick Start
535///
536/// ```rust,ignore
537/// use actix_web::{App, HttpServer, web};
538/// use html2pdf_api::prelude::*;
539/// use html2pdf_api::integrations::actix::configure_routes;
540///
541/// #[actix_web::main]
542/// async fn main() -> std::io::Result<()> {
543///     let pool = init_browser_pool().await.unwrap();
544///
545///     HttpServer::new(move || {
546///         App::new()
547///             .app_data(web::Data::new(pool.clone()))
548///             .configure(configure_routes)
549///     })
550///     .bind("127.0.0.1:8080")?
551///     .run()
552///     .await
553/// }
554/// ```
555///
556/// # Available Exports
557///
558/// | Export | Description |
559/// |--------|-------------|
560/// | `configure_routes` | Configure all pre-built routes |
561/// | `pdf_from_url` | Handler for URL-to-PDF |
562/// | `pdf_from_html` | Handler for HTML-to-PDF |
563/// | `pool_stats` | Handler for pool statistics |
564/// | `health_check` | Handler for health check |
565/// | `readiness_check` | Handler for readiness check |
566/// | `SharedPool` | Type alias for `Arc<BrowserPool>` |
567/// | `BrowserPoolData` | Type alias for `web::Data<SharedBrowserPool>` |
568/// | `BrowserPoolActixExt` | Extension trait for `BrowserPool` |
569///
570/// See [`crate::integrations::actix`] for full documentation.
571#[cfg(feature = "actix-integration")]
572pub mod actix {
573    pub use crate::integrations::actix::*;
574}
575
576/// Rocket integration module.
577///
578/// Provides pre-built handlers and helpers for Rocket 0.5.x.
579///
580/// # Quick Start
581///
582/// ```rust,ignore
583/// use html2pdf_api::prelude::*;
584/// use html2pdf_api::integrations::rocket::routes;
585///
586/// #[rocket::launch]
587/// async fn launch() -> _ {
588///     let pool = init_browser_pool().await.unwrap();
589///
590///     rocket::build()
591///         .manage(pool)
592///         .mount("/", routes())
593/// }
594/// ```
595///
596/// # Available Exports
597///
598/// | Export | Description |
599/// |--------|-------------|
600/// | `routes` | Get all pre-built routes |
601/// | `pdf_from_url` | Handler for URL-to-PDF |
602/// | `pdf_from_html` | Handler for HTML-to-PDF |
603/// | `pool_stats` | Handler for pool statistics |
604/// | `health_check` | Handler for health check |
605/// | `readiness_check` | Handler for readiness check |
606/// | `SharedPool` | Type alias for `Arc<BrowserPool>` |
607///
608/// See [`crate::integrations::rocket`] for full documentation.
609#[cfg(feature = "rocket-integration")]
610pub mod rocket {
611    pub use crate::integrations::rocket::*;
612}
613
614/// Axum integration module.
615///
616/// Provides pre-built handlers and router for Axum 0.7.x/0.8.x.
617///
618/// # Quick Start
619///
620/// ```rust,ignore
621/// use html2pdf_api::prelude::*;
622/// use html2pdf_api::integrations::axum::router;
623///
624/// #[tokio::main]
625/// async fn main() {
626///     let pool = init_browser_pool().await.unwrap();
627///
628///     let app = router().with_state(pool);
629///
630///     let listener = tokio::net::TcpListener::bind("127.0.0.1:8080")
631///         .await
632///         .unwrap();
633///     axum::serve(listener, app).await.unwrap();
634/// }
635/// ```
636///
637/// # Available Exports
638///
639/// | Export | Description |
640/// |--------|-------------|
641/// | `router` | Create router with all pre-built routes |
642/// | `pdf_from_url` | Handler for URL-to-PDF |
643/// | `pdf_from_html` | Handler for HTML-to-PDF |
644/// | `pool_stats` | Handler for pool statistics |
645/// | `health_check` | Handler for health check |
646/// | `readiness_check` | Handler for readiness check |
647/// | `SharedPool` | Type alias for `Arc<BrowserPool>` |
648///
649/// See [`crate::integrations::axum`] for full documentation.
650#[cfg(feature = "axum-integration")]
651pub mod axum {
652    pub use crate::integrations::axum::*;
653}
654
655// ============================================================================
656// Tests
657// ============================================================================
658
659#[cfg(test)]
660mod tests {
661    use super::*;
662
663    /// Verify all core types are accessible.
664    #[test]
665    fn test_core_types_exported() {
666        // These should all compile, proving the types are exported
667        fn _accepts_config(_: BrowserPoolConfig) {}
668        fn _accepts_error(_: BrowserPoolError) {}
669        fn _accepts_stats(_: PoolStats) {}
670        fn _returns_result() -> Result<()> {
671            Ok(())
672        }
673    }
674
675    /// Verify Arc is re-exported.
676    #[test]
677    fn test_std_reexports() {
678        let _: Arc<i32> = Arc::new(42);
679    }
680
681    /// Verify SharedBrowserPool type alias works.
682    #[test]
683    fn test_shared_browser_pool_type() {
684        fn _accepts_shared_pool(_: SharedBrowserPool) {}
685
686        // Verify it's Arc<BrowserPool>
687        fn _verify_type() {
688            let pool = BrowserPool::builder()
689                .factory(Box::new(crate::factory::mock::MockBrowserFactory::new()))
690                .build()
691                .unwrap();
692
693            let shared: SharedBrowserPool = Arc::new(pool);
694            _accepts_shared_pool(shared);
695        }
696    }
697
698    /// Verify env-config exports when feature is enabled.
699    #[cfg(feature = "env-config")]
700    #[test]
701    fn test_env_config_exports() {
702        // These should compile when env-config is enabled
703        let _: Option<String> = chrome_path_from_env();
704        fn _takes_from_env(_: fn() -> crate::error::Result<BrowserPoolConfig>) {}
705        _takes_from_env(from_env);
706    }
707
708    /// Verify service types when any integration is enabled.
709    #[cfg(any(
710        feature = "actix-integration",
711        feature = "rocket-integration",
712        feature = "axum-integration"
713    ))]
714    #[test]
715    fn test_service_types_exported() {
716        let _: PdfFromUrlRequest = PdfFromUrlRequest::default();
717        let _: PdfFromHtmlRequest = PdfFromHtmlRequest::default();
718        let _: HealthResponse = HealthResponse::default();
719    }
720}