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 
11 use crate::{Utf8Path, Utf8PathBuf};
12 use 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")]
23 impl Arbitrary for Utf8PathBuf {
24     type Parameters = <String as Arbitrary>::Parameters;
25     type Strategy = BoxedStrategy<Self>;
26 
arbitrary_with(args: Self::Parameters) -> Self::Strategy27     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")]
53 impl Arbitrary for Box<Utf8Path> {
54     type Parameters = <Utf8PathBuf as Arbitrary>::Parameters;
55     type Strategy = MapInto<StrategyFor<Utf8PathBuf>, Self>;
56 
arbitrary_with(args: Self::Parameters) -> Self::Strategy57     fn arbitrary_with(args: Self::Parameters) -> Self::Strategy {
58         any_with::<Utf8PathBuf>(args).prop_map_into()
59     }
60 }
61