web_static_pack/
lib.rs

1//! web-static-pack is the "loader" (2nd stage) part of the
2//! [web-static-pack](https://github.com/peku33/web-static-pack)
3//! project. See project page for a general idea how two parts cooperate.
4//!
5//! Once a `pack` is created with build script / CI / build.rs using
6//! [web-static-pack-packer](https://crates.io/crates/web-static-pack-packer)
7//! it will usually be included in your target application with
8//! <https://docs.rs/include_bytes_aligned/latest/include_bytes_aligned/>.
9//! Then it will be loaded with a [loader::load], utilizing zero-copy
10//! deserialization (so file contents will be sent from executable contents
11//! directly). The pack is then possibly wrapped with [responder::Responder]
12//! http service and used with a web server like hyper.
13//!
14//! The main part of this crate is [responder::Responder]. Its
15//! [responder::Responder::respond_flatten] method makes a [http] service - a
16//! function taking [http::Request] parts (method, path, headers) and returning
17//! [http::Response].
18//!
19//! To make a [responder::Responder], a [common::pack::Pack] is needed. It can
20//! be obtained by [loader::load] function by passing (possibly included in
21//! binary) contents of a `pack` created with the packer.
22//!
23//! # Examples
24//!
25//! ## Creating and calling responder
26//! ```ignore
27//! use anyhow::Error;
28//! use include_bytes_aligned::include_bytes_aligned;
29//! use http::{HeaderMap, Method, StatusCode};
30//! use web_static_pack::{loader::load, responder::Responder};
31//!
32//! // assume we have a vcard-personal-portfolio.pack available from packer examples
33//! static PACK_ARCHIVED_SERIALIZED: &[u8] =
34//!    include_bytes_aligned!(16, "vcard-personal-portfolio.pack");
35//!
36//! fn main() -> Result<(), Error> {
37//!     // load (map / cast) [common::pack::PackArchived] from included bytes
38//!     let pack_archived = unsafe { load(PACK_ARCHIVED_SERIALIZED).unwrap() };
39//!
40//!     // create a responder from `pack`
41//!     let responder = Responder::new(pack_archived);
42//!
43//!     // do some checks on the responder
44//!     assert_eq!(
45//!         responder.respond_flatten(
46//!             &Method::GET,
47//!             "/present",
48//!             &HeaderMap::default(),
49//!         ).status(),
50//!         StatusCode::OK
51//!     );
52//!
53//!     Ok(())
54//! }
55//! ```
56//!
57//! ## Adapting to hyper service
58//! This example is based on
59//! <https://hyper.rs/guides/1/server/graceful-shutdown/>
60//! which is a bit complicated.
61//!
62//! You can run full working example from
63//! `tests/examples/vcard_personal_portfolio_server.rs`
64//!
65//! ```ignore
66//! use anyhow::Error;
67//! use web_static_pack::responder::Responder;
68//! use std::{
69//!     convert::Infallible,
70//!     mem::transmute,
71//! };
72//!
73//! #[tokio::main(flavor = "current_thread")]
74//! async fn main() -> Result<(), Error> {
75//!     // lets assume we have a `responder: Responder` object available from previous example
76//!     // hyper requires service to be static
77//!     // we use graceful, no connections will outlive server function
78//!     let responder = unsafe {
79//!         transmute::<
80//!             &Responder<'_, _>,
81//!             &Responder<'static, _>,
82//!         >(&responder)
83//!     };
84//!
85//!     // make hyper service
86//!     let service_fn = service_fn(|request| async {
87//!         // you can probably filter your /api requests here
88//!         let (parts, _body) = request.into_parts();
89//!
90//!         let response = responder.respond_flatten(
91//!             &parts.method,
92//!             parts.uri.path(),
93//!             &parts.headers
94//!         );
95//!
96//!         Ok::<_, Infallible>(response)
97//!     });
98//!
99//!     // use service_fn like in hyper example
100//!     Ok(())
101//! }
102//! ```
103
104#![allow(clippy::new_without_default)]
105#![allow(clippy::let_and_return)]
106#![warn(missing_docs)]
107
108pub use web_static_pack_common as common;
109
110pub mod body;
111pub mod cache_control;
112pub mod content_encoding;
113pub mod file;
114pub mod loader;
115pub mod pack;
116pub mod responder;