From b7b9dc586ef806cc1e4f4102c8b105421fe4ff29 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sun, 11 Oct 2026 14:50:39 -0700 Subject: [PATCH] Add `Dir::create_new`, analogous to `File::create_new` The Rust standard library added `File::create_new` as a shorthand, to avoid requiring `OpenOptions` for a common case. Add an analogous `Dir::create_new`. --- cap-std/src/fs/dir.rs | 12 ++++++++++++ cap-std/src/fs_utf8/dir.rs | 10 ++++++++++ tests/fs.rs | 11 ++++++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/cap-std/src/fs/dir.rs b/cap-std/src/fs/dir.rs index 71619eee..c8030635 100644 --- a/cap-std/src/fs/dir.rs +++ b/cap-std/src/fs/dir.rs @@ -202,6 +202,18 @@ impl Dir { ) } + /// Creates a new file in read-write mode; error if the file already exists. + /// + /// This corresponds to [`std::fs::File::create_new`], but only accesses paths relative to + /// `self`. + #[inline] + pub fn create_new>(&self, path: P) -> io::Result { + self.open_with( + path, + OpenOptions::new().read(true).write(true).create_new(true), + ) + } + /// Returns the canonical form of a path with all intermediate components /// normalized and symbolic links resolved. /// diff --git a/cap-std/src/fs_utf8/dir.rs b/cap-std/src/fs_utf8/dir.rs index 6a34deb9..cf804cb5 100644 --- a/cap-std/src/fs_utf8/dir.rs +++ b/cap-std/src/fs_utf8/dir.rs @@ -143,6 +143,16 @@ impl Dir { self.cap_std.create(path).map(File::from_cap_std) } + /// Creates a new file in read-write mode; error if the file already exists. + /// + /// This corresponds to [`std::fs::File::create_new`], but only accesses paths relative to + /// `self`. + #[inline] + pub fn create_new>(&self, path: P) -> io::Result { + let path = from_utf8(path.as_ref())?; + self.cap_std.create_new(path).map(File::from_cap_std) + } + /// Returns the canonical form of a path with all intermediate components /// normalized and symbolic links resolved. /// diff --git a/tests/fs.rs b/tests/fs.rs index 2009d475..1a61814e 100644 --- a/tests/fs.rs +++ b/tests/fs.rs @@ -519,7 +519,7 @@ fn file_test_directoryinfo_readdir() { } #[test] -fn file_create_new_already_exists_error() { +fn file_create_new_via_openoptions_already_exists_error() { let tmpdir = tmpdir(); let file = "file_create_new_error_exists"; check!(tmpdir.create(file)); @@ -529,6 +529,15 @@ fn file_create_new_already_exists_error() { assert_eq!(e.kind(), ErrorKind::AlreadyExists); } +#[test] +fn file_create_new_already_exists_error() { + let tmpdir = tmpdir(); + let file = "file_create_new_error_exists"; + check!(tmpdir.create(file)); + let e = tmpdir.create_new(file).unwrap_err(); + assert_eq!(e.kind(), ErrorKind::AlreadyExists); +} + #[test] fn mkdir_path_already_exists_error() { let tmpdir = tmpdir();