camino/
proptest_impls.rs

1// Copyright (c) The camino Contributors
2// SPDX-License-Identifier: MIT OR Apache-2.0
3
4//! [proptest::Arbitrary](Arbitrary) implementation for `Utf8PathBuf` and `Box<Utf8Path>`.  Note
5//! that implementions for `Rc<Utf8Path>` and `Arc<Utf8Path>` are not currently possible due to
6//! orphan rules - this crate doesn't define `Rc`/`Arc` nor `Arbitrary`, so it can't define those
7//! implementations.
8
9// NOTE: #[cfg(feature = "proptest1")] is specified here to work with `doc_cfg`.
10
11use crate::{Utf8Path, Utf8PathBuf};
12use proptest::{arbitrary::StrategyFor, prelude::*, strategy::MapInto};
13
14/// The [`Arbitrary`] impl for `Utf8PathBuf` returns a path with between 0 and 8 components,
15/// joined by the [`MAIN_SEPARATOR`](std::path::MAIN_SEPARATOR) for the platform. (Each component is
16/// randomly generated, and may itself contain one or more separators.)
17///
18/// On Unix, this generates an absolute path half of the time and a relative path the other half.
19///
20/// On Windows, this implementation doesn't currently generate
21/// [`Utf8PrefixComponent`](crate::Utf8PrefixComponent) instances, though in the future it might.
22#[cfg(feature = "proptest1")]
23impl Arbitrary for Utf8PathBuf {
24    type Parameters = <String as Arbitrary>::Parameters;
25    type Strategy = BoxedStrategy<Self>;
26
27    fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
28        (
29            any::<bool>(),
30            prop::collection::vec(any_with::<String>(args), 0..8),
31        )
32            .prop_map(|(is_relative, components)| {
33                let initial_component = if is_relative {
34                    Some(format!("{}", std::path::MAIN_SEPARATOR))
35                } else {
36                    None
37                };
38                initial_component.into_iter().chain(components).collect()
39            })
40            .boxed()
41    }
42}
43
44/// The [`Arbitrary`] impl for `Box<Utf8Path>` returns a path with between 0 and 8 components,
45/// joined by the [`MAIN_SEPARATOR`](std::path::MAIN_SEPARATOR) for the platform. (Each component is
46/// randomly generated, and may itself contain one or more separators.)
47///
48/// On Unix, this generates an absolute path half of the time and a relative path the other half.
49///
50/// On Windows, this implementation doesn't currently generate
51/// [`Utf8PrefixComponent`](crate::Utf8PrefixComponent) instances, though in the future it might.
52#[cfg(feature = "proptest1")]
53impl Arbitrary for Box<Utf8Path> {
54    type Parameters = <Utf8PathBuf as Arbitrary>::Parameters;
55    type Strategy = MapInto<StrategyFor<Utf8PathBuf>, Self>;
56
57    fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
58        any_with::<Utf8PathBuf>(args).prop_map_into()
59    }
60}