web_static_pack_packer/lib.rs
1//! web-static-pack-packer is the "builder" (1st 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//! The goal of the packer part is to collect your directories / files / memory
6//! slices, precalculate things like `ETag`, compressed versions (`gzip`,
7//! `brotli`) and store them as a single file (called `pack`). Your target
8//! application will include (ex. with
9//! <https://docs.rs/include_bytes_aligned/latest/include_bytes_aligned/>
10//! ) and "load" / "parse" `pack` during runtime using
11//! [web-static-pack](https://crates.io/crates/web-static-pack)
12//! (the loader part) and (possibly) serve it with a web server of your choice.
13//!
14//! This crate is usually used in build script / CI / build.rs stage, not in
15//! your target application. It's used to create a `pack` from list of files
16//! (like your GUI app / images / other assets) to be later loaded by your app
17//! and served with a web server.
18//!
19//! This crate can be used in two ways:
20//! - As a standalone application, installed with `cargo install`, this is the
21//! preferred way if you are using build scripts, CI pipeline etc.
22//! - As a library, imported to your project, this is a way to go if you want to
23//! use it in build.rs of your target application or go with some really
24//! custom approach
25//!
26//! # Using as a standalone application
27//!
28//! ## Install (or update to matching version)
29//! - Either install it with `$ cargo install web-static-pack-packer` and use
30//! shell command `$ web-static-pack-packer [PARAMS]...`
31//! - Or clone repo, go into `packer` directory, `$ cargo run --release --
32//! [PARAMS]...`. (please note `--` which marks end of arguments for cargo run
33//! and beginning of arguments for the application).
34//!
35//! For the purpose of this example, the first option is assumed, with
36//! `web-static-pack-packer` command available.
37//!
38//! ## Create a `pack`
39//! `web-static-pack-packer` provides up to date documentation with `$
40//! web-static-pack-packer --help`. Application is built around subcommands to
41//! cover basic scenarios:
42//! - `directory-single [OPTIONS] <INPUT_DIRECTORY_PATH> <OUTPUT_FILE_PATH>`
43//! will create a `pack` from a single directory. This is the most common
44//! scenario, for example when you have a web application built into
45//! `./gui/build` directory and you want to have it served with your app.
46//! - `files-cmd [OPTIONS] <OUTPUT_FILE_PATH> <INPUT_BASE_DIRECTORY_PATH>
47//! [INPUT_FILE_PATHS]...` lets you specify all files from command line in
48//! `xargs` style. base directory path is used as a root for building relative
49//! paths inside a `pack`.
50//! - `files-stdin [OPTIONS] <INPUT_BASE_DIRECTORY_PATH> <OUTPUT_FILE_PATH>`
51//! lets you provide list of files from stdin.
52//!
53//! ### Examples
54//! Let's say you have a `vcard-personal-portfolio` directory containing your
55//! web project (available in tests/data/ in repository). Directory structure
56//! looks like:
57//! ```text
58//! vcard-personal-portfolio
59//! | index.html
60//! | index.txt
61//! +---assets
62//! | +---css
63//! | | style.css
64//! | +---images
65//! | | <some files>.png
66//! | \---js
67//! | script.js
68//! \---website-demo-image
69//! desktop.png
70//! mobile.png
71//! ```
72//! By running:
73//! ```text
74//! $ web-static-pack-packer \
75//! directory-single \
76//! ./vcard-personal-portfolio \
77//! ./vcard-personal-portfolio.pack
78//! ```
79//! a new file `vcard-personal-portfolio.pack` will be created, containing all
80//! files, so that `GET /index.html` or `GET /assets/css/tyle.css` or `GET
81//! /website-demo-image/mobile.png` will be correctly resolved.
82//!
83//! In the next step, the `vcard-personal-portfolio.pack` should be used by
84//! [web-static-pack](https://crates.io/crates/web-static-pack)
85//! (the loader part) to serve it from your app.
86//!
87//! # Using as a library
88//! When using as a library, you are most likely willing to create a loadable
89//! (by the loader) `pack`, by using [pack::Builder].
90//!
91//! You will need to add [file_pack_path::FilePackPath] (file + path) objects to
92//! the builder, which you can obtain by:
93//! - Manually constructing the object from [common::pack_path::PackPath] and
94//! [common::file::File] (obtained from fs [file::build_from_path] or memory
95//! slice [file::build_from_content]).
96//! - Reading single file with [file_pack_path::FilePackPath::build_from_path].
97//! - Automatic search through fs with [directory::search].
98//!
99//! When all files are added to the builder, you will need to finalize it and
100//! either write to fs (to have it included in your target application) with
101//! [pack::store_file] or (mostly for test purposes) serialize to memory with
102//! [pack::store_memory].
103//!
104//! ### Examples
105//! This example will do exactly the same as one for application scenario:
106//! ```no_run
107//! # use anyhow::Error;
108//! # use std::path::PathBuf;
109//! # use web_static_pack_packer::{
110//! # directory::{search, SearchOptions},
111//! # file::BuildFromPathOptions,
112//! # pack::{store_file, Builder},
113//! # };
114//!
115//! # fn main() -> Result<(), Error> {
116//! // start with empty pack builder
117//! let mut pack = Builder::new();
118//!
119//! // add files with directory search and default options
120//! pack.file_pack_paths_add(search(
121//! &PathBuf::from("vcard-personal-portfolio"),
122//! &SearchOptions::default(),
123//! &BuildFromPathOptions::default(),
124//! )?)?;
125//!
126//! // finalize the builder, obtain pack
127//! let pack = pack.finalize();
128//!
129//! // store (serialize `pack` to the fs) to be included in the target app
130//! store_file(&pack, &PathBuf::from("vcard-personal-portfolio.pack"))?;
131//! # Ok(())
132//! # }
133//! ```
134//!
135//! For more examples browse through modules of this crate.
136
137#![allow(clippy::new_without_default)]
138#![warn(missing_docs)]
139
140pub use web_static_pack_common as common;
141
142pub mod directory;
143pub mod file;
144pub mod file_pack_path;
145pub mod pack;
146pub mod pack_path;