use serde::{Deserialize, Deserializer, Serialize, de};
use std::sync::Arc;
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(untagged)]
pub enum PrintPageRange {
Integer(u64),
Range(Arc<str>),
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default, rename_all = "camelCase")]
pub struct PrintParameters {
pub orientation: PrintOrientation,
#[serde(deserialize_with = "deserialize_to_print_scale_f64")]
pub scale: f64,
pub background: bool,
pub page: PrintPage,
pub margin: PrintMargins,
pub page_ranges: Arc<[PrintPageRange]>,
pub shrink_to_fit: bool,
}
impl Default for PrintParameters {
fn default() -> Self {
PrintParameters {
orientation: PrintOrientation::default(),
scale: 1.0,
background: false,
page: PrintPage::default(),
margin: PrintMargins::default(),
page_ranges: Arc::new([]),
shrink_to_fit: true,
}
}
}
#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum PrintOrientation {
Landscape,
#[default]
Portrait,
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PrintPage {
#[serde(deserialize_with = "deserialize_to_positive_f64")]
pub width: f64,
#[serde(deserialize_with = "deserialize_to_positive_f64")]
pub height: f64,
}
impl Default for PrintPage {
fn default() -> Self {
PrintPage {
width: 21.59,
height: 27.94,
}
}
}
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
#[serde(default)]
pub struct PrintMargins {
pub top: f64,
pub bottom: f64,
pub left: f64,
pub right: f64,
}
impl Default for PrintMargins {
fn default() -> Self {
PrintMargins {
top: 1.0,
bottom: 1.0,
left: 1.0,
right: 1.0,
}
}
}
fn deserialize_to_positive_f64<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
D: Deserializer<'de>,
{
let val = f64::deserialize(deserializer)?;
if val < 0.0 {
return Err(de::Error::custom(format!("{} is negative", val)));
};
Ok(val)
}
fn deserialize_to_print_scale_f64<'de, D>(deserializer: D) -> Result<f64, D::Error>
where
D: Deserializer<'de>,
{
let val = f64::deserialize(deserializer)?;
if !(0.1..=2.0).contains(&val) {
return Err(de::Error::custom(format!("{} is outside range 0.1-2", val)));
};
Ok(val)
}