Skip to content

Commit 401a42c

Browse files
authored
dir: Add convenience functions for accessing UTF-8 variants (#362)
I'd like to make use of the fs_utf8 bits in some of my code, but doing so is tricky as switching `Dir` types quickly becomes "infectious" across the codebase and forces a larger conversion all at once. Adding these these two convenience APIs on `Dir` (the non-UTF8 version) I think greatly improve the ergonomics for the common cases where I may want to *view* an existing `Dir` entries (without creating a new file descriptor) and iterate over its entries, and to conveniently open a child dir as a utf-8 version. There are more methods we could add, but these feel like a useful start to me.
1 parent 076ab49 commit 401a42c

File tree

3 files changed

+36
-2
lines changed

3 files changed

+36
-2
lines changed

cap-std/src/fs/dir.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#[cfg(target_os = "wasi")]
22
use crate::fs::OpenOptionsExt;
33
use crate::fs::{DirBuilder, File, Metadata, OpenOptions, ReadDir};
4+
#[cfg(feature = "fs_utf8")]
5+
use crate::fs_utf8::Dir as DirUtf8;
46
#[cfg(unix)]
57
use crate::os::unix::net::{UnixDatagram, UnixListener, UnixStream};
68
#[cfg(not(target_os = "wasi"))]
@@ -109,6 +111,16 @@ impl Dir {
109111
Ok(Self::from_std_file(dir))
110112
}
111113

114+
/// Attempts to open a directory, verifying UTF-8.
115+
///
116+
/// This is equivalent to [`crate::fs_utf8::Dir::open_dir`].
117+
#[inline]
118+
#[cfg(feature = "fs_utf8")]
119+
pub fn open_dir_utf8<P: AsRef<camino::Utf8Path>>(&self, path: P) -> io::Result<DirUtf8> {
120+
let path = crate::fs_utf8::from_utf8(path.as_ref())?;
121+
self.open_dir(path).map(DirUtf8::from_cap_std)
122+
}
123+
112124
/// Creates a new, empty directory at the provided path.
113125
///
114126
/// This corresponds to [`std::fs::create_dir`], but only accesses paths
@@ -261,6 +273,15 @@ impl Dir {
261273
read_base_dir(&self.std_file).map(|inner| ReadDir { inner })
262274
}
263275

276+
/// Returns an iterator over UTF-8 entries within `self`.
277+
///
278+
/// Equivalent to [`crate::fs_utf8::Dir::read_dir`].
279+
#[inline]
280+
#[cfg(feature = "fs_utf8")]
281+
pub fn entries_utf8(&self) -> io::Result<crate::fs_utf8::ReadDir> {
282+
self.entries().map(crate::fs_utf8::ReadDir::from_cap_std)
283+
}
284+
264285
/// Returns an iterator over the entries within a directory.
265286
///
266287
/// This corresponds to [`std::fs::read_dir`], but only accesses paths

cap-std/src/fs_utf8/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@ pub use camino;
3838
use camino::{Utf8Path, Utf8PathBuf};
3939

4040
#[cfg(not(feature = "arf_strings"))]
41-
fn from_utf8<'a>(path: &'a Utf8Path) -> std::io::Result<&'a std::path::Path> {
41+
pub(crate) fn from_utf8<'a>(path: &'a Utf8Path) -> std::io::Result<&'a std::path::Path> {
4242
Ok(path.as_std_path())
4343
}
4444

4545
#[cfg(feature = "arf_strings")]
46-
fn from_utf8<'a>(path: &'a Utf8Path) -> std::io::Result<std::path::PathBuf> {
46+
pub(crate) fn from_utf8<'a>(path: &'a Utf8Path) -> std::io::Result<std::path::PathBuf> {
4747
#[cfg(not(windows))]
4848
let path = {
4949
#[cfg(unix)]

tests/fs_utf8.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,3 +1680,16 @@ fn test_invalid_utf8() {
16801680
}
16811681
}
16821682
}
1683+
1684+
#[test]
1685+
fn from_cap_std() {
1686+
let tmpdir = sys_common::io::tmpdir();
1687+
let dir = "d1/d2";
1688+
check!(tmpdir.create_dir_all(dir));
1689+
let d1_entry = tmpdir.entries_utf8().unwrap().next().unwrap().unwrap();
1690+
assert_eq!(d1_entry.file_name().unwrap(), "d1");
1691+
1692+
let d1 = tmpdir.open_dir_utf8("d1").unwrap();
1693+
let d2_entry = d1.entries().unwrap().next().unwrap().unwrap();
1694+
assert_eq!(d2_entry.file_name().unwrap(), "d2");
1695+
}

0 commit comments

Comments
 (0)