use std::path::*;
use crate::{
arbitrary::{SMapped, StrategyFor},
path::PathParams,
prelude::{any, any_with, Arbitrary, Strategy},
std_facade::{string::ToString, Arc, Box, Rc, String, Vec},
strategy::{statics::static_map, MapInto},
};
arbitrary!(StripPrefixError; Path::new("").strip_prefix("a").unwrap_err());
#[derive(Debug)]
pub struct PathParamsOutput {
is_absolute: bool,
components: Vec<String>,
}
impl Arbitrary for PathParamsOutput {
type Parameters = PathParams;
type Strategy = SMapped<(bool, Vec<String>), Self>;
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
static_map(
(
any::<bool>(),
any_with::<Vec<String>>((
args.components(),
args.component_regex(),
)),
),
|(is_absolute, components)| Self {
is_absolute,
components,
},
)
}
}
impl Arbitrary for PathBuf {
type Parameters = PathParams;
type Strategy = SMapped<PathParamsOutput, Self>;
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
static_map(
any_with::<PathParamsOutput>(args),
|PathParamsOutput {
is_absolute,
components,
}| {
let mut out = PathBuf::new();
if is_absolute {
out.push(&MAIN_SEPARATOR.to_string());
}
for component in components {
let component = component
.chars()
.filter(|&c| !std::path::is_separator(c))
.collect::<String>();
out.push(&component);
}
out
},
)
}
}
macro_rules! dst_wrapped {
($($w: ident),*) => {
$(
impl Arbitrary for $w<Path> {
type Parameters = PathParams;
type Strategy = MapInto<StrategyFor<PathBuf>, Self>;
fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
any_with::<PathBuf>(args).prop_map_into()
}
}
)*
}
}
dst_wrapped!(Box, Rc, Arc);
#[cfg(test)]
mod test {
no_panic_test!(
strip_prefix_error => StripPrefixError,
path_buf => PathBuf,
box_path => Box<Path>,
rc_path => Rc<Path>,
arc_path => Arc<Path>
);
}