#![allow(clippy::cast_precision_loss, clippy::cast_sign_loss, clippy::unused_self)]
use crate::options::validation::normalize_token;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum PreprocessingPreset {
Minimal,
#[default]
Standard,
Aggressive,
}
impl PreprocessingPreset {
#[must_use]
pub fn parse(value: &str) -> Self {
match normalize_token(value).as_str() {
"minimal" => Self::Minimal,
"aggressive" => Self::Aggressive,
_ => Self::Standard,
}
}
}
#[derive(Debug, Clone)]
#[cfg_attr(
any(feature = "serde", feature = "metadata"),
derive(serde::Serialize, serde::Deserialize)
)]
#[cfg_attr(any(feature = "serde", feature = "metadata"), serde(default, deny_unknown_fields))]
pub struct PreprocessingOptions {
pub enabled: bool,
pub preset: PreprocessingPreset,
pub remove_navigation: bool,
pub remove_forms: bool,
}
#[derive(Debug, Clone, Default)]
#[cfg_attr(
any(feature = "serde", feature = "metadata"),
derive(serde::Serialize, serde::Deserialize)
)]
#[cfg_attr(any(feature = "serde", feature = "metadata"), serde(deny_unknown_fields))]
pub struct PreprocessingOptionsUpdate {
pub enabled: Option<bool>,
pub preset: Option<PreprocessingPreset>,
pub remove_navigation: Option<bool>,
pub remove_forms: Option<bool>,
}
impl Default for PreprocessingOptions {
fn default() -> Self {
Self {
enabled: true,
preset: PreprocessingPreset::default(),
remove_navigation: true,
remove_forms: true,
}
}
}
impl PreprocessingOptions {
#[allow(clippy::needless_pass_by_value)]
pub const fn apply_update(&mut self, update: PreprocessingOptionsUpdate) {
if let Some(enabled) = update.enabled {
self.enabled = enabled;
}
if let Some(preset) = update.preset {
self.preset = preset;
}
if let Some(remove_navigation) = update.remove_navigation {
self.remove_navigation = remove_navigation;
}
if let Some(remove_forms) = update.remove_forms {
self.remove_forms = remove_forms;
}
}
#[must_use]
pub fn from_update(update: PreprocessingOptionsUpdate) -> Self {
let mut options = Self::default();
options.apply_update(update);
options
}
}
impl From<PreprocessingOptionsUpdate> for PreprocessingOptions {
fn from(update: PreprocessingOptionsUpdate) -> Self {
Self::from_update(update)
}
}
#[cfg(any(feature = "serde", feature = "metadata"))]
mod serde_impls {
use super::PreprocessingPreset;
use serde::{Deserialize, Serializer};
impl<'de> Deserialize<'de> for PreprocessingPreset {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = String::deserialize(deserializer)?;
Ok(Self::parse(&value))
}
}
impl serde::Serialize for PreprocessingPreset {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = match self {
Self::Minimal => "minimal",
Self::Standard => "standard",
Self::Aggressive => "aggressive",
};
serializer.serialize_str(s)
}
}
}
#[cfg(all(test, any(feature = "serde", feature = "metadata")))]
mod tests {
use super::*;
#[test]
fn test_preprocessing_options_serde() {
let options = PreprocessingOptions {
enabled: true,
preset: PreprocessingPreset::Aggressive,
remove_navigation: false,
..Default::default()
};
let json = serde_json::to_string(&options).expect("Failed to serialize");
let deserialized: PreprocessingOptions = serde_json::from_str(&json).expect("Failed to deserialize");
assert!(deserialized.enabled);
assert_eq!(deserialized.preset, PreprocessingPreset::Aggressive);
assert!(!deserialized.remove_navigation);
}
}