diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-07 05:48:48 +0000 |
commit | ef24de24a82fe681581cc130f342363c47c0969a (patch) | |
tree | 0d494f7e1a38b95c92426f58fe6eaa877303a86c /vendor/proptest/src/arbitrary/_std | |
parent | Releasing progress-linux version 1.74.1+dfsg1-1~progress7.99u1. (diff) | |
download | rustc-ef24de24a82fe681581cc130f342363c47c0969a.tar.xz rustc-ef24de24a82fe681581cc130f342363c47c0969a.zip |
Merging upstream version 1.75.0+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'vendor/proptest/src/arbitrary/_std')
-rw-r--r-- | vendor/proptest/src/arbitrary/_std/path.rs | 112 |
1 files changed, 110 insertions, 2 deletions
diff --git a/vendor/proptest/src/arbitrary/_std/path.rs b/vendor/proptest/src/arbitrary/_std/path.rs index e7d063c17..2e71b03db 100644 --- a/vendor/proptest/src/arbitrary/_std/path.rs +++ b/vendor/proptest/src/arbitrary/_std/path.rs @@ -11,13 +11,121 @@ use std::path::*; -// TODO: Figure out PathBuf and then Box/Rc/Box<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()); +/// A private type (not actually pub) representing the output of [`PathParams`] that can't be +/// referred to by API users. +/// +/// The goal of this type is to encapsulate the output of `PathParams`. If this layer weren't +/// present, the type of `<PathBuf as Arbitrary>::Strategy` would be `SMapped<(bool, Vec<String>), +/// Self>`. This is a problem because it exposes the internal representation of `PathParams` as an +/// API. For example, if an additional parameter of randomness (e.g. another bool) were added, the +/// type of `Strategy` would change. +/// +/// With `PathParamsOutput`, the type of `Strategy` is `SMapped<PathParamsOutput, Self>`, which is a +/// type that can't be named directly---only via `<PathBuf as Arbitrary>::Strategy`. The internal +/// representation of `PathParams` can be changed without affecting the API. +#[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, + }, + ) + } +} + +/// This implementation accepts as its argument a [`PathParams`] struct. It generates either a +/// relative or an absolute path with equal probability. +/// +/// Currently, this implementation does not generate: +/// +/// * Paths that are not valid UTF-8 (this is unlikely to change) +/// * Paths with a [`PrefixComponent`](std::path::PrefixComponent) on Windows, e.g. `C:\` (this may +/// change in the future) +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 { + // If a component has an embedded / (or \ on Windows), remove it from the + // string. + let component = component + .chars() + .filter(|&c| !std::path::is_separator(c)) + .collect::<String>(); + out.push(&component); + } + + out + }, + ) + } +} + +macro_rules! dst_wrapped { + ($($w: ident),*) => { + $( + /// This implementation is identical to [the `Arbitrary` implementation for + /// `PathBuf`](trait.Arbitrary.html#impl-Arbitrary-for-PathBuf). + 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 + strip_prefix_error => StripPrefixError, + path_buf => PathBuf, + box_path => Box<Path>, + rc_path => Rc<Path>, + arc_path => Arc<Path> ); } |