use std::collections::HashMap;
use std::borrow::Cow;
use crate::types::*;
use crate::util::*;
use serde::{Serialize, Deserialize};
impl<'a> Cleaner<'a> {
pub fn with_profiles(self, profiles: ProfilesConfig) -> ProfiledCleaner<'a> {
ProfiledCleaner {
profiles: profiles.make(self.params),
cleaner: UnprofiledCleaner {
docs : self.docs,
commons: self.commons,
actions: self.actions
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct ProfiledCleaner<'a> {
cleaner: UnprofiledCleaner<'a>,
profiles: Profiles<'a>
}
impl<'a> ProfiledCleaner<'a> {
pub fn cleaner(&self) -> &UnprofiledCleaner<'a> {
&self.cleaner
}
pub fn profiles(&self) -> &Profiles<'a> {
&self.profiles
}
pub fn with_profile(&'a self, name: Option<&str>) -> Option<Cleaner<'a>> {
Some(Cleaner {
docs : Cow::Borrowed(&*self.cleaner.docs),
params : self.profiles.get(name)?.params().borrowed(),
commons: Cow::Borrowed(&*self.cleaner.commons),
actions: Cow::Borrowed(&*self.cleaner.actions)
})
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq, Deserialize, Serialize, Suitability)]
#[serde(deny_unknown_fields)]
pub struct UnprofiledCleaner<'a> {
#[serde(default, skip_serializing_if = "is_default")]
pub docs: Cow<'a, CleanerDocs>,
#[serde(default, skip_serializing_if = "is_default")]
pub commons: Cow<'a, Commons>,
#[serde(default, skip_serializing_if = "is_default")]
pub actions: Cow<'a, [Action]>
}
impl<'a> UnprofiledCleaner<'a> {
pub fn borrowed(&'a self) -> Self {
Self {
docs : Cow::Borrowed(&*self.docs),
commons: Cow::Borrowed(&*self.commons),
actions: Cow::Borrowed(&*self.actions)
}
}
pub fn with_profile(&'a self, profile: &'a Profile) -> Cleaner<'a> {
Cleaner {
docs : Cow::Borrowed(&*self.docs),
params : profile.params.borrowed(),
commons: Cow::Borrowed(&*self.commons),
actions: Cow::Borrowed(&*self.actions)
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Profiles<'a> {
base: Profile<'a>,
profiles: HashMap<String, Profile<'a>>
}
impl<'a> Profiles<'a> {
pub fn names(&self) -> impl Iterator<Item = &str> {
self.profiles.keys().map(String::as_str)
}
pub fn get(&'a self, name: Option<&str>) -> Option<&'a Profile<'a>> {
match name {
None => Some(&self.base),
Some(name) => self.profiles.get(name)
}
}
pub fn into_profile(mut self, name: Option<&str>) -> Option<Profile<'a>> {
match name {
None => Some(self.base),
Some(name) => self.profiles.remove(name)
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct Profile<'a> {
params_diff: ParamsDiff,
#[serde(skip)]
params: Params<'a>
}
impl<'a> Profile<'a> {
pub fn params(&self) -> &Params<'a> {
&self.params
}
pub fn params_diff(&self) -> &ParamsDiff {
&self.params_diff
}
}
impl From<Profile<'_>> for ParamsDiff {
fn from(value: Profile) -> Self {
value.params_diff
}
}
impl<'a> From<Profile<'a>> for Params<'a> {
fn from(value: Profile<'a>) -> Self {
value.params
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
#[serde(deny_unknown_fields)]
pub struct ProfiledCleanerConfig<'a> {
pub cleaner: Cleaner<'a>,
pub profiles: ProfilesConfig
}
impl<'a> ProfiledCleanerConfig<'a> {
pub fn make(self) -> ProfiledCleaner<'a> {
ProfiledCleaner {
profiles: self.profiles.make(self.cleaner.params),
cleaner: UnprofiledCleaner {
docs : self.cleaner.docs,
commons: self.cleaner.commons,
actions: self.cleaner.actions
}
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
pub struct ProfilesConfig {
#[serde(default, skip_serializing_if = "is_default")]
pub base: ProfileConfig,
#[serde(default, skip_serializing_if = "is_default")]
pub profiles: HashMap<String, ProfileConfig>
}
impl ProfilesConfig {
pub fn get<'a>(&'a self, name: Option<&str>) -> Option<&'a ProfileConfig> {
match name {
None => Some(&self.base),
Some(name) => self.profiles.get(name)
}
}
pub fn into_params<'a>(mut self, name: Option<&str>, mut params: Params<'a>) -> Option<Params<'a>> {
self.base.params_diff.apply_once(&mut params);
match name {
None => Some(params),
Some(name) => {
self.profiles.remove(name)?.params_diff.apply_once(&mut params);
Some(params)
}
}
}
pub fn make(self, params: Params) -> Profiles {
let base = self.base.make(params);
Profiles {
profiles: self.profiles.into_iter().map(|(name, profile)| (name, profile.make(base.params().clone()))).collect(),
base
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Default)]
#[serde(deny_unknown_fields)]
pub struct ProfileConfig {
#[serde(default, skip_serializing_if = "is_default")]
pub params_diff: ParamsDiff
}
impl ProfileConfig {
pub fn make(self, mut params: Params) -> Profile {
Profile {
params: {self.params_diff.apply_multiple(&mut params); params},
params_diff: self.params_diff
}
}
}