use std::fmt::Debug;
use std::collections::{HashSet, HashMap};
use std::borrow::Cow;
use std::path::{Path, PathBuf};
use std::rc::Rc;
use std::sync::Arc;
use crate::types::*;
pub(crate) use url_cleaner_macros::Suitability;
pub(crate) trait Suitability: Debug {
fn assert_suitability(&self, config: &Cleaner);
}
macro_rules! always_suitable {
($($t:ty),+) => {
$(impl Suitability for $t {fn assert_suitability(&self, _: &Cleaner) {}})+
}
}
always_suitable!(char, str, String, u8, u16, u32, u64, u128, usize, i8, i16, i32, i64, i128, isize, f32, f64, bool, url::Url, BetterUrl, serde_json::Value, serde_json::Number, Path, PathBuf, std::time::Duration);
#[cfg(feature = "http")] always_suitable!(reqwest::header::HeaderMap, reqwest::header::HeaderValue, reqwest::Method);
pub(crate) fn set_is_documented(name: &StringSource, config: &Cleaner) {
if let StringSource::String(name) = name {
assert!(config.params.sets.contains_key(name), "Unset Set: {name}");
assert!(config.docs.sets.contains_key(name), "Undocumented Set: {name}");
}
}
pub(crate) fn map_is_documented(name: &StringSource, config: &Cleaner) {
if let StringSource::String(name) = name {
assert!(config.params.maps.contains_key(name), "Unset Map: {name}");
assert!(config.docs.maps.contains_key(name), "Undocumented Map: {name}");
}
}
pub(crate) fn named_partitioning_is_documented(name: &StringSource, config: &Cleaner) {
if let StringSource::String(name) = name {
assert!(config.params.named_partitionings.contains_key(name), "Unset NamedPartitioning: {name}");
assert!(config.docs.named_partitionings.contains_key(name), "Undocumented NamedPartitioning: {name}");
}
}
impl<K: Suitability, V: Suitability> Suitability for HashMap<K, V> {
fn assert_suitability(&self, config: &Cleaner) {
for (k, v) in self.iter() {
k.assert_suitability(config);
v.assert_suitability(config);
}
}
}
impl<T: Suitability> Suitability for HashSet<T> {
fn assert_suitability(&self, config: &Cleaner) {
for x in self.iter() {
x.assert_suitability(config)
}
}
}
impl<T: Suitability> Suitability for Vec<T> {
fn assert_suitability(&self, config: &Cleaner) {
for x in self.iter() {
x.assert_suitability(config)
}
}
}
impl<T: Suitability> Suitability for [T] {
fn assert_suitability(&self, config: &Cleaner) {
for x in self.iter() {
x.assert_suitability(config)
}
}
}
impl<T: Suitability + ?Sized> Suitability for Box<T> {
fn assert_suitability(&self, config: &Cleaner) {
(**self).assert_suitability(config)
}
}
impl<T: Suitability> Suitability for Option<T> {
fn assert_suitability(&self, config: &Cleaner) {
if let Some(x) = self {x.assert_suitability(config);}
}
}
impl<'a, T: Suitability + ToOwned + ?Sized + 'a> Suitability for Cow<'a, T> where <T as ToOwned>::Owned: Suitability {
fn assert_suitability(&self, config: &Cleaner) {
(**self).assert_suitability(config)
}
}
impl<T: Suitability + ?Sized> Suitability for Rc<T> {
fn assert_suitability(&self, config: &Cleaner) {
(**self).assert_suitability(config)
}
}
impl<T: Suitability + ?Sized> Suitability for Arc<T> {
fn assert_suitability(&self, config: &Cleaner) {
(**self).assert_suitability(config)
}
}