Skip to content

Commit 112e1f5

Browse files
committed
Convert macro to output PathBuf directly
1 parent f2631fd commit 112e1f5

File tree

3 files changed

+42
-54
lines changed

3 files changed

+42
-54
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2020

2121
## Unreleased
2222

23+
#### Added
24+
- Converted macro to output PathBuf directly
25+
- Discouraged manual use of PathDSL
26+
2327
## v0.5.4
2428

2529
Released 2019-08-25

src/lib.rs

Lines changed: 33 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66
//! # Overview
77
//!
88
//! ```rust
9-
//! use path_dsl::{path, PathDSL};
9+
//! use path_dsl::path;
1010
//! # use std::path::{PathBuf, Path};
1111
//!
1212
//! // PathBuf::push() only called once with consecutive literals:
13-
//! let literals: PathDSL = path!("dir1" | "dir2" | "dir3");
13+
//! let literals: PathBuf = path!("dir1" | "dir2" | "dir3");
1414
//! // Type annotation for illustration purposes; not needed
1515
//!
1616
//! // Does not copy data if first path segment is a owning value:
@@ -49,38 +49,18 @@
4949
//! # combined_pb.push("middle_folder");
5050
//! # combined_pb.push("file.txt");
5151
//! # assert_eq!(combined, combined_pb);
52-
//!
53-
//! // Usable like a PathBuf
54-
//! let mut empty = path!();
55-
//! empty.push("folder");
56-
//! # let mut empty_pb = PathBuf::new();
57-
//! # empty_pb.push("folder");
58-
//! # assert_eq!(empty, empty_pb);
59-
//!
60-
//! // Free conversions to/from a PathBuf
61-
//! fn pathbuf_function(p: PathDSL) -> PathBuf {
62-
//! // Into converts to/from all types that PathBuf.into() does
63-
//! path!(p | "file.txt").into()
64-
//! }
65-
//! let non_empty: PathDSL = pathbuf_function(empty).into();
66-
//! # let mut non_empty_pb = PathBuf::new();
67-
//! # non_empty_pb.push("folder");
68-
//! # non_empty_pb.push("file.txt");
69-
//! # assert_eq!(non_empty, non_empty_pb);
7052
//! ```
7153
//!
7254
//! # PathDSL Macro and Type
7355
//!
74-
//! PathDSL's [`path!`](macro.path.html) macro allows for the creation of the type `PathDSL` in the most efficent way possible in the situation.
75-
//! PathDSL is a drop-in replacement for PathBuf and is easily and cheeply convertable back and forth. This
76-
//! macro has a couple optimizations over just using the PathDSL class manually, described later.
56+
//! PathDSL's [`path!`](macro.path.html) macro allows for the creation of a `PathBuf` in the most efficent way possible in the situation.
7757
//!
7858
//! note the use of `|` instead of `/` due to rust's macro rules
7959
//!
8060
//! ```rust
81-
//! use path_dsl::{path, PathDSL};
61+
//! use path_dsl::path;
8262
//! // Type annotation for illustration only, not needed
83-
//! let path: PathDSL = path!("dir1" | "dir2" | "dir3" | "file.txt");
63+
//! let path: PathBuf = path!("dir1" | "dir2" | "dir3" | "file.txt");
8464
//!
8565
//! # use std::path::PathBuf;
8666
//! # let mut path2 = PathBuf::new();
@@ -93,7 +73,9 @@
9373
//!
9474
//! ### PathDSL
9575
//!
96-
//! You can also generate a PathDSL directly, though this is discouraged.
76+
//! You can also generate a PathDSL directly, though this is discouraged. PathDSL will pretend to be
77+
//! a `PathBuf` as best it can, but it is almost always more efficent to use the `path!` macro to generate
78+
//! a `PathBuf` directly.
9779
//!
9880
//! ```rust
9981
//! use path_dsl::PathDSL;
@@ -123,8 +105,8 @@
123105
//! let other = PathBuf::from("some_dir");
124106
//! let filename: &str = "my_file.txt";
125107
//!
126-
//! let mac = path!("dir1" | "dir2" | &other | filename); // Preferred
127-
//! let path = PathDSL::from("dir1") / "dir2" / other / filename; // Also works
108+
//! let mac: PathBuf = path!("dir1" | "dir2" | &other | filename); // Preferred
109+
//! let path: PathDSL = PathDSL::from("dir1") / "dir2" / other / filename; // Also works
128110
//!
129111
//! # use std::path::PathBuf;
130112
//! # let mut path2 = PathBuf::new();
@@ -146,14 +128,14 @@
146128
//! Both mutable and immutable borrows are supported, though they will never actually mutate anything.
147129
//!
148130
//! ```rust,compile_fail
149-
//! use path_dsl::{path, PathDSL};
131+
//! use path_dsl::path;
150132
//! # use std::path::PathBuf;
151133
//!
152134
//! let value = PathBuf::from("some_dir");
153135
//! let borrow: &str = "my_file.txt";
154136
//!
155137
//! let mac = path!(value | borrow);
156-
//! let path = PathDSL::new() / value / borrow; // Will not compile because `value` was moved
138+
//! let path = path!(value | borrow); // Will not compile because `value` was moved
157139
//! ```
158140
//!
159141
//! You must manually borrow it:
@@ -177,6 +159,9 @@
177159
//!
178160
//! ### PathDSL <=> PathBuf
179161
//!
162+
//! **The PathDSL type is not meant to be used directly, but exists to allow the macro to work.
163+
//! It was once intended to be directly used, so it ratains this functionality.**
164+
//!
180165
//! `PathDSL` is designed to be a drop-in replacement for `PathBuf`, including trivial conversions
181166
//! between the two. In any situation where you would be able to use `PathBuf` you can use
182167
//! `PathDSL`. `PathDSL` includes an implementation of `Deref` to a `PathBuf` (and by proxy `Path`) and re-implements all functions that take `self`, so is fully api compatable.
@@ -219,7 +204,7 @@
219204
//! func(buf);
220205
//! // Must convert into `PathBuf`
221206
//! // Dereferencing doesn't work because `func` moves.
222-
//! func(dsl.into_pathbuf());
207+
//! func(dsl.to_path_buf());
223208
//! # let dsl = path!("file.txt");
224209
//! func(dsl.into()) // also works
225210
//! ```
@@ -267,12 +252,6 @@
267252
//! # assert_eq!(p, dup);
268253
//! ```
269254
//!
270-
//! # Known Issues
271-
//!
272-
//! Due to my mitigation of a [rustc bug](https://github.com/rust-lang/rust/issues/63460) there may be
273-
//! issues when renaming `path_dsl` crate and using the [`path!`](macro.path.html) macro. I currently have not have
274-
//! experienced this, but if it happens, please report an issue and I'll add it to the documentation.
275-
//!
276255
//! # Why Use A Crate?
277256
//!
278257
//! You may be wondering why you should use a crate for this when you can easily wrap `PathBuf` and
@@ -305,6 +284,9 @@ use std::rc::Rc;
305284
use std::str::FromStr;
306285
use std::sync::Arc;
307286

287+
#[cfg(test)]
288+
mod tests;
289+
308290
/// A PathBuf wrapper that has support for a Path DSL.
309291
///
310292
/// It is usable nearly identically to a PathBuf.
@@ -1077,6 +1059,13 @@ impl Into<PathDSL> for CopylessDSL {
10771059
}
10781060
}
10791061

1062+
impl Into<PathBuf> for CopylessDSL {
1063+
#[inline(always)]
1064+
fn into(self) -> PathBuf {
1065+
PathBuf::new()
1066+
}
1067+
}
1068+
10801069
impl Div<PathDSL> for CopylessDSL {
10811070
type Output = PathDSL;
10821071

@@ -1186,8 +1175,7 @@ macro_rules! separator {
11861175
#[macro_export]
11871176
macro_rules! concat_separator {
11881177
( $e:literal, $($other:literal),+ ) => {
1189-
// Working around https://github.com/rust-lang/rust/issues/63460
1190-
concat!($e, path_dsl::separator!(), path_dsl::concat_separator!($($other),+))
1178+
concat!($e, $crate::separator!(), $crate::concat_separator!($($other),+))
11911179
};
11921180
( $e:literal ) => {
11931181
$e
@@ -1283,7 +1271,7 @@ macro_rules! path_impl {
12831271
};
12841272
}
12851273

1286-
/// Efficient macro for creating a `PathDSL`.
1274+
/// Efficient macro for creating a `PathBuf`.
12871275
///
12881276
/// General usage documentation is available at the [crate root](index.html). The following is
12891277
/// documentation of the optimizations made and internal implementation details.
@@ -1300,10 +1288,11 @@ macro_rules! path_impl {
13001288
///
13011289
/// ```rust
13021290
/// # use path_dsl::{CopylessDSL, PathDSL, path};
1291+
/// # use std::path::PathBuf;
13031292
/// # let ret1 =
13041293
/// path!("concat" | "optimization");
13051294
/// # let res2 =
1306-
/// Into::<PathDSL>::into(CopylessDSL::new() / "concat/optimization");
1295+
/// Into::<PathBuf>::into(CopylessDSL::new() / "concat/optimization");
13071296
/// # assert_eq!(ret1, res2);
13081297
/// ```
13091298
///
@@ -1316,7 +1305,7 @@ macro_rules! path_impl {
13161305
/// path!(owning_path | "concat" | "optimization");
13171306
/// # let owning_path = PathBuf::new();
13181307
/// # let res2 =
1319-
/// Into::<PathDSL>::into(CopylessDSL::new() / owning_path / "concat/optimization");
1308+
/// Into::<PathBuf>::into(CopylessDSL::new() / owning_path / "concat/optimization");
13201309
/// # assert_eq!(ret1, res2);
13211310
/// ```
13221311
///
@@ -1329,7 +1318,7 @@ macro_rules! path_impl {
13291318
/// path!("concat" | "optimization" | owning_path | "other_thing");
13301319
/// # let owning_path = PathBuf::new();
13311320
/// # let res2 =
1332-
/// Into::<PathDSL>::into(CopylessDSL::new() / "concat/optimization" / owning_path / "other_thing");
1321+
/// Into::<PathBuf>::into(CopylessDSL::new() / "concat/optimization" / owning_path / "other_thing");
13331322
/// # assert_eq!(ret1, res2);
13341323
/// ```
13351324
///
@@ -1381,7 +1370,7 @@ macro_rules! path_impl {
13811370
#[macro_export]
13821371
macro_rules! path {
13831372
( $($other:tt)* ) => {
1384-
::std::convert::Into::<$crate::PathDSL>::into($crate::path_impl!( @($crate::CopylessDSL::new())@ $($other)* ));
1373+
::std::convert::Into::<std::path::PathBuf>::into($crate::path_impl!( @($crate::CopylessDSL::new())@ $($other)* ));
13851374
};
13861375
() => { $crate::PathDSL::new() };
13871376
}

tests/unit-tests.rs renamed to src/tests.rs

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
//! Why are these unit tests not in the `lib.rs` file? Because of my mitigation of
2-
//! a [rustc bug](https://github.com/rust-lang/rust/issues/63460), I manually use the full
3-
//! path to some of my macros. This means I cannot call the macro within my own module.
4-
//! Therefore, I have to bring the unit tests out to where the integration tests normally are.
5-
1+
use crate::{path, PathDSL};
62
use more_asserts::*;
7-
use path_dsl::{path, PathDSL};
83
use std::borrow::Cow;
94
use std::ffi::{OsStr, OsString};
105
use std::path::{Path, PathBuf};
@@ -64,10 +59,10 @@ owned_dsl_test!(constructor: gen_cow_osstr, name: arc_osstr);
6459
fn gen_box_path(p: &str) -> Box<Path> {
6560
Box::from(Path::new(p))
6661
}
67-
fn gen_cow_path(p: &str) -> Cow<Path> {
62+
fn gen_cow_path(p: &str) -> Cow<'_, Path> {
6863
Cow::from(Path::new(p))
6964
}
70-
fn gen_cow_osstr(p: &str) -> Cow<OsStr> {
65+
fn gen_cow_osstr(p: &str) -> Cow<'_, OsStr> {
7166
Cow::from(OsStr::new(p))
7267
}
7368

@@ -146,5 +141,5 @@ into_test!(type: PathDSL, name: dsl);
146141
into_test!(type: Box<Path>, name: box_path);
147142
into_test!(type: Arc<Path>, name: arc_path);
148143
into_test!(type: Rc<Path>, name: rc_path);
149-
into_test!(type: Cow<Path>, converter: (&), name: cow_path);
150-
into_test!(type: Cow<OsStr>, converter: (&), name: cow_osstr);
144+
into_test!(type: Cow<'_, Path>, converter: (&), name: cow_path);
145+
into_test!(type: Cow<'_, OsStr>, converter: (&), name: cow_osstr);

0 commit comments

Comments
 (0)