use std::time::Duration;
use utils::duration_to_millis;
cfg_if! {
if #[cfg(target_os = "macos")] {
fn default_zoom() -> f32 {3.5}
} else {
fn default_zoom() -> f32 {1.0}
}
}
#[derive(Clone, Debug)]
pub(crate) struct Settings {
disable_external_links: bool,
disable_javascript: bool,
enable_forms: bool,
dpi: usize,
grayscale: bool,
image_dpi: usize,
image_quality: usize,
low_quality: bool,
javascript_delay: Duration,
margin_bottom: String,
margin_left: String,
margin_right: String,
margin_top: String,
no_background: bool,
no_images: bool,
no_pdf_compression: bool,
orientation: Orientation,
page_size: PageSize,
zoom: f32,
}
impl Default for Settings {
fn default() -> Settings {
Settings {
disable_external_links: false,
disable_javascript: false,
enable_forms: false,
dpi: 96,
grayscale: false,
image_dpi: 600,
image_quality: 94,
low_quality: false,
javascript_delay: Duration::from_millis(200),
margin_bottom: String::from("0.5in"),
margin_left: String::from("0.5in"),
margin_right: String::from("0.5in"),
margin_top: String::from("0.5in"),
no_background: false,
no_images: false,
no_pdf_compression: false,
orientation: Orientation::Portrait,
page_size: PageSize::Letter,
zoom: default_zoom(),
}
}
}
impl Settings {
pub(crate) fn to_arguments(&self) -> Vec<String> {
let mut arguments = Vec::new();
if self.disable_external_links {
arguments.push("--disable-external-links".to_string());
}
if self.disable_javascript {
arguments.push("--disable-javascript".to_string());
}
if self.enable_forms {
arguments.push("--enable-forms".to_string());
}
arguments.extend_from_slice(&["--dpi".to_string(), self.dpi.to_string()]);
if self.grayscale {
arguments.push("--grayscale".to_string());
}
arguments.extend_from_slice(&["--image-dpi".to_string(), self.image_dpi.to_string()]);
arguments.extend_from_slice(&["--image-quality".to_string(), self.image_quality.to_string()]);
if self.low_quality {
arguments.push("--low-quality".to_string());
}
arguments.extend_from_slice(&["--javascript-delay".to_string(), duration_to_millis(self.javascript_delay).to_string()]);
arguments.extend_from_slice(&["--margin-bottom".to_string(), self.margin_bottom.clone()]);
arguments.extend_from_slice(&["--margin-left".to_string(), self.margin_left.clone()]);
arguments.extend_from_slice(&["--margin-right".to_string(), self.margin_right.clone()]);
arguments.extend_from_slice(&["--margin-top".to_string(), self.margin_top.clone()]);
if self.no_background {
arguments.push("--no-background".to_string());
}
if self.no_images {
arguments.push("--no-images".to_string());
}
if self.no_pdf_compression {
arguments.push("--no-pdf-compression".to_string());
}
arguments.extend_from_slice(&["--orientation".to_string(), self.orientation.clone().into()]);
arguments.extend_from_slice(&["--page-size".to_string(), self.page_size.clone().into()]);
arguments.extend_from_slice(&["--zoom".to_string(), format!("{:.2}", self.zoom)]);
arguments
}
pub(crate) fn set(&mut self, setting: Setting) {
use self::Setting::*;
match setting {
DisableExternalLinks(v) => self.disable_external_links = v,
DisableJavascript(v) => self.disable_javascript = v,
EnableForms(v) => self.enable_forms = v,
Dpi(v) => self.dpi = v,
Grayscale(v) => self.grayscale = v,
ImageDpi(v) => self.image_dpi = v,
ImageQuality(v) => self.image_quality = v,
LowQuality(v) => self.low_quality = v,
JavascriptDelay(v) => self.javascript_delay = v,
MarginBottom(v) => self.margin_bottom = v,
MarginLeft(v) => self.margin_left = v,
MarginRight(v) => self.margin_right = v,
MarginTop(v) => self.margin_top = v,
NoBackground(v) => self.no_background = v,
NoImages(v) => self.no_images = v,
NoPdfCompression(v) => self.no_pdf_compression = v,
Orientation(v) => self.orientation = v,
PageSize(v) => self.page_size = v,
Zoom(v) => self.zoom = v,
};
}
}
#[cfg_attr(nightly, feature(non_exhaustive))]
#[derive(Clone, Debug)]
pub enum Setting {
DisableExternalLinks(bool),
DisableJavascript(bool),
EnableForms(bool),
Dpi(usize),
Grayscale(bool),
ImageDpi(usize),
ImageQuality(usize),
LowQuality(bool),
JavascriptDelay(Duration),
MarginBottom(String),
MarginLeft(String),
MarginRight(String),
MarginTop(String),
NoBackground(bool),
NoImages(bool),
NoPdfCompression(bool),
Orientation(Orientation),
PageSize(PageSize),
Zoom(f32),
}
#[allow(missing_docs)]
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum Orientation {
Landscape,
Portrait,
}
impl From<Orientation> for String {
fn from(orientation: Orientation) -> String {
use self::Orientation::*;
match orientation {
Landscape => "Landscape".to_string(),
Portrait => "Portrait".to_string(),
}
}
}
#[derive(Clone, Debug, Eq, PartialEq, Ord, PartialOrd, Hash)]
pub enum PageSize {
A0,
A1,
A2,
A3,
A4,
A5,
A6,
A7,
A8,
A9,
B0,
B1,
B2,
B3,
B4,
B5,
B6,
B7,
B8,
B9,
B10,
C5E,
Comm10E,
DLE,
Executive,
Folio,
Ledger,
Legal,
Letter,
Tabloid,
}
impl From<PageSize> for String {
fn from(page_size: PageSize) -> String {
use self::PageSize::*;
match page_size {
A0 => "A0".to_string(),
A1 => "A1".to_string(),
A2 => "A2".to_string(),
A3 => "A3".to_string(),
A4 => "A4".to_string(),
A5 => "A5".to_string(),
A6 => "A6".to_string(),
A7 => "A7".to_string(),
A8 => "A8".to_string(),
A9 => "A9".to_string(),
B0 => "B0".to_string(),
B1 => "B1".to_string(),
B2 => "B2".to_string(),
B3 => "B3".to_string(),
B4 => "B4".to_string(),
B5 => "B5".to_string(),
B6 => "B6".to_string(),
B7 => "B7".to_string(),
B8 => "B8".to_string(),
B9 => "B9".to_string(),
B10 => "B10".to_string(),
C5E => "C5E".to_string(),
Comm10E => "Comm10E".to_string(),
DLE => "DLE".to_string(),
Executive => "Executive".to_string(),
Folio => "Folio".to_string(),
Ledger => "Ledgar".to_string(),
Legal => "Legal".to_string(),
Letter => "Letter".to_string(),
Tabloid => "Tabloid".to_string(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_to_arguments() {
let settings = Settings {
disable_external_links: true,
disable_javascript: true,
enable_forms: true,
dpi: 100,
grayscale: true,
image_dpi: 101,
image_quality: 102,
low_quality: true,
javascript_delay: Duration::from_millis(2000),
margin_bottom: "0.1in".to_string(),
margin_left: "0.2in".to_string(),
margin_right: "0.3in".to_string(),
margin_top: "0.4in".to_string(),
no_background: true,
no_images: true,
no_pdf_compression: true,
orientation: Orientation::Landscape,
page_size: PageSize::A4,
zoom: 2.0,
};
let arguments = settings.to_arguments();
let mut s = String::new();
for argument in arguments {
s = format!("{} {}", s, argument);
}
let output = s.trim();
let desired = "--disable-external-links --disable-javascript --enable-forms \
--dpi 100 --grayscale --image-dpi 101 --image-quality 102 --low-quality \
--javascript-delay 2000 --margin-bottom 0.1in --margin-left 0.2in \
--margin-right 0.3in --margin-top 0.4in --no-background --no-images \
--no-pdf-compression --orientation Landscape --page-size A4 --zoom 2.00";
assert_eq!(desired, output);
}
}