diff --git a/core/CHANGELOG.md b/core/CHANGELOG.md index a9a2c315..48019822 100644 --- a/core/CHANGELOG.md +++ b/core/CHANGELOG.md @@ -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 diff --git a/core/src/lib.rs b/core/src/lib.rs index 4d0ca373..439e5f03 100644 --- a/core/src/lib.rs +++ b/core/src/lib.rs @@ -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 + }}; +} diff --git a/core/src/path.rs b/core/src/path.rs index 901172c2..afe1f409 100644 --- a/core/src/path.rs +++ b/core/src/path.rs @@ -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();