Skip to content

Commit

Permalink
core: Add path_buf macro
Browse files Browse the repository at this point in the history
We already have the path macro and PathBuf::from_path.  Having a
separate path_buf macro makes the code more readable and ensures
compile-time evaluation.
  • Loading branch information
robin-nitrokey committed Jan 16, 2025
1 parent 51cae4d commit 2c66535
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 1 deletion.
1 change: 1 addition & 0 deletions core/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
- Make `Path` and `PathBuf` more const-friendly:
- Make `Path::as_ptr` and `PathBuf::from_buffer_unchecked` const.
- Add const `Path::const_eq`, `PathBuf::from_path`, `PathBuf::as_path` and `PathBuf::as_str` methods.
- Add `path_buf` macro to construct a `PathBuf` from a string literal.

## [v0.1.0](https://github.com/trussed-dev/littlefs2/releases/tag/core-0.1.0) - 2024-10-17

Expand Down
44 changes: 44 additions & 0 deletions core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,47 @@ macro_rules! path {
_PATH
}};
}

/// Creates an owned path from a string without a trailing null.
///
/// Panics and causes a compiler error if the string contains null bytes or non-ascii characters.
///
/// # Examples
///
/// ```
/// use littlefs2_core::{path_buf, PathBuf};
///
/// const HOME: PathBuf = path_buf!("/home");
/// let root = path_buf!("/");
/// ```
///
/// Illegal values:
///
/// ```compile_fail
/// # use littlefs2_core::{path_buf, PathBuf};
/// const WITH_NULL: PathBuf = path_buf!("/h\0me"); // does not compile
/// ```
///
/// ```compile_fail
/// # use littlefs2_core::{path_buf, PathBuf};
/// const WITH_UTF8: PathBuf = path_buf!("/höme"); // does not compile
/// ```
///
/// The macro enforces const evaluation so that compilation fails for illegal values even if the
/// macro is not used in a const context:
///
/// ```compile_fail
/// # use littlefs2_core::path_buf;
/// let path = path_buf!("te\0st"); // does not compile
/// ```
#[macro_export]
macro_rules! path_buf {
($path:literal) => {{
const _PATH: $crate::PathBuf =
match $crate::Path::from_str_with_nul(::core::concat!($path, "\0")) {
Ok(path) => $crate::PathBuf::from_path(path),
Err(_) => panic!("invalid littlefs2 path"),
};
_PATH
}};
}
5 changes: 4 additions & 1 deletion core/src/path.rs
Original file line number Diff line number Diff line change
Expand Up @@ -473,11 +473,14 @@ impl PathBuf {
/// This method is a const-friendly version of the `From<&Path>` implementation. If you don’t
/// need a const method, prefer `From<&Path>` as it is more idiomatic and more efficient.
///
/// The [`path_buf`][] can be used instead to construct a `PathBuf` from a literal.
///
/// # Example
///
/// ```
/// # use littlefs2_core::{path, PathBuf};
/// # use littlefs2_core::{path, path_buf, PathBuf};
/// const PATH: PathBuf = PathBuf::from_path(path!("test"));
/// assert_eq!(PATH, path_buf!("test"));
/// ```
pub const fn from_path(path: &Path) -> Self {
let bytes = path.inner.to_bytes();
Expand Down

0 comments on commit 2c66535

Please sign in to comment.