html5_picture/lib.rs
1//! *The documentation is still a work in progress, so if you have questions,
2//! you are welcome to [create an issue](https://github.com/emirror-de/html5-picture). :-)*
3//!
4//! ## Purpose
5//!
6//! Supports the binary within this package.
7//! Contains functions to easily generate different sizes of a picture that
8//! can be used on webpages. Also offers the possibility to convert them into webp
9//! format and is able to create `<picture>` tags for the given images.
10//!
11//! Currently this crate is only capable of converting `png` files to webp using
12//! `cwebp`.
13//! So make sure that webp is installed on your computer.
14//!
15//! ## Installation
16//!
17//! The binary can be installed via `cargo install html5-picture`. As stated
18//! before, make sure webp is installed before using.
19//!
20//! ## Usage
21//!
22//! Use `html5-picture --help` for an overview of all parameters.
23//!
24//! ## Examples
25//!
26//! ### Conversion with three scales and 70% quality
27//! If you want to create three different sizes of the images in `./assets`
28//! with a conversion quality of 70%, enter the following command:
29//!
30//! ```bash
31//! html5-picture ./assets 3 -q 70
32//! ```
33//!
34//! This will convert your images and save them to `./assets-html5picture`.
35//! This folder is also the working directory make sure to not modify it while
36//! the application is running.
37//!
38//! ### Conversion with given installation folder
39//! If you pass `-i <folder_name>` as parameter, the resulting files are
40//! moved from the working directory to the given `<folder_name>` after conversion
41//! and scaling.
42//!
43//! ```bash
44//! html5-picture ./assets 3 -q 100 -i ./assets-build
45//! ```
46//!
47//! In this example the images are installted to `./assets-build`.
48//!
49//! ### Force overwriting
50//! Using the `-f` or `--force-overwrite` flag will overwrite existing webp or
51//! HTML5 picture tag files.
52//!
53//! ```bash
54//! html5-picture ./assets 3 -q 100 -i ./dist -f
55//! ```
56//!
57//! ### Writing picture tag files to disk
58//! With the `-p` option, it is possible to save the `<picture>` tags to disk.
59//! However it is recommended to use it in combination with -m, which sets the
60//! mountpoint in your tag files for you.
61//!
62//! ```bash
63//! html5-picture ./assets 4 -i ./dist -p ./html5-tags -m /some/web-server/mountpoint
64//! ```
65//!
66//! ### Read input files by JSON
67//! **Upcoming feature.**
68//! The pictures can be defined using JSON format. `html5-picture` will read it
69//! from stdin. This enables definition of all attributes such as `alt` per image.
70#[deny(missing_docs)]
71#[deny(rustdoc::missing_crate_level_docs)]
72#[deny(rustdoc::broken_intra_doc_links)]
73#[deny(rustdoc::private_intra_doc_links)]
74use {
75 crate::core::{
76 collect_file_names,
77 copy_originals_to_output,
78 create_all_output_directories,
79 install_images_into,
80 process_images,
81 save_html_picture_tags,
82 Config,
83 State,
84 },
85 indicatif::ProgressBar,
86 log::error,
87 queue::Queue,
88 std::path::PathBuf,
89 walkdir::WalkDir,
90};
91
92/// Contains default functions and traits.
93pub mod core;
94
95/// Generic helper functions.
96pub mod utils;
97
98/// Support for webp format. Used mainly for conversion.
99pub mod webp;
100
101/// Path processing that is required for ```html5_picture```
102pub mod path;
103
104/// Functions operating on the filesystem that is required for ```html5_picture```
105pub mod fs;
106
107/// HTML5 related functions, such as creation of picture tags.
108pub mod html5;
109
110/// Determines if the given input filename contains a .png extension.
111pub fn is_png(input: &PathBuf) -> bool {
112 match input.extension() {
113 Some(s) => match s.to_str() {
114 None => false,
115 Some(v) => v == "png",
116 },
117 None => false,
118 }
119}
120
121/// Collects all png file names that are stored in the ```input_dir```.
122pub fn collect_png_file_names(
123 input_dir: &PathBuf,
124 progressbar: Option<ProgressBar>,
125) -> Vec<PathBuf> {
126 let mut file_names = vec![];
127 for entry in WalkDir::new(&input_dir) {
128 // unwrap the entry
129 let entry = if let Err(msg) = &entry {
130 error!("{}", msg.to_string());
131 continue;
132 } else {
133 entry.unwrap()
134 };
135 let entry = entry.into_path();
136
137 if let Some(ref pb) = progressbar {
138 pb.tick();
139 }
140
141 if !is_png(&entry) {
142 continue;
143 }
144 file_names.push(entry);
145 }
146 file_names
147}
148
149/// The main function of the binary. Executes all required steps for copying,
150/// conversion and installationn of the source images.
151pub fn run(config: Config) {
152 if !&config.input_dir.exists() {
153 error!("Input directory does not exist!");
154 return;
155 }
156 match &config.scaled_images_count {
157 0 => {
158 error!("Minimum scaled images count is 1!");
159 return;
160 }
161 _ => (),
162 }
163
164 // add all default processes
165 let mut q: Queue<fn(&mut State)> = Queue::new();
166 q.queue(collect_file_names).unwrap();
167 q.queue(create_all_output_directories).unwrap();
168 q.queue(copy_originals_to_output).unwrap();
169
170 // finally add processing step
171 q.queue(process_images).unwrap();
172
173 // optional steps
174 if let Some(_) = &config.install_images_into {
175 q.queue(install_images_into).unwrap();
176 }
177 if let Some(_) = &config.picture_tags_output_folder {
178 q.queue(save_html_picture_tags).unwrap();
179 }
180
181 let mut s = State::new(config, q.len());
182
183 while let Some(step_function) = s.dequeue(&mut q) {
184 step_function(&mut s);
185 }
186}