Skip to content

Commit beea85a

Browse files
committed
Switch to custom FileTypeExt traits.
std has recently sealed its `FileTypeExt` traits, so cap-primitives can no longer implement them for its own types. Fortunately, these traits are just used as extension traits, so we can just define our own copies of them, and implement those instead. Fixes #270.
1 parent 862983e commit beea85a

File tree

8 files changed

+61
-35
lines changed

8 files changed

+61
-35
lines changed

cap-async-std/src/fs/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,10 @@ pub use read_dir::ReadDir;
3737
#[cfg(not(target_os = "wasi"))]
3838
pub use cap_primitives::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};
3939

40+
// Re-export conditional types from `cap_primitives`.
41+
#[cfg(any(unix, target_os = "vxworks", all(windows, windows_file_type_ext)))]
42+
pub use cap_primitives::fs::FileTypeExt;
43+
4044
// Re-export things from `async_std` that we can use as-is.
4145
#[cfg(target_os = "wasi")]
4246
pub use async_std::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};

cap-async-std/src/fs_utf8/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ pub use read_dir::ReadDir;
2222
// Re-export things from `cap_std::fs` that we can use as-is.
2323
pub use crate::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};
2424

25+
// Re-export conditional types from `cap_primitives`.
26+
#[cfg(any(unix, target_os = "vxworks", all(windows, windows_file_type_ext)))]
27+
pub use cap_primitives::fs::FileTypeExt;
28+
2529
// Re-export `camino` to make it easy for users to depend on the same
2630
// version we do, because we use its types in our public API.
2731
pub use camino;

cap-fs-ext/src/file_type_ext.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,22 @@ impl FileTypeExt for std::fs::FileType {
6767
impl FileTypeExt for cap_primitives::fs::FileType {
6868
#[inline]
6969
fn is_block_device(&self) -> bool {
70-
std::os::unix::fs::FileTypeExt::is_block_device(self)
70+
cap_primitives::fs::FileTypeExt::is_block_device(self)
7171
}
7272

7373
#[inline]
7474
fn is_char_device(&self) -> bool {
75-
std::os::unix::fs::FileTypeExt::is_char_device(self)
75+
cap_primitives::fs::FileTypeExt::is_char_device(self)
7676
}
7777

7878
#[inline]
7979
fn is_fifo(&self) -> bool {
80-
std::os::unix::fs::FileTypeExt::is_fifo(self)
80+
cap_primitives::fs::FileTypeExt::is_fifo(self)
8181
}
8282

8383
#[inline]
8484
fn is_socket(&self) -> bool {
85-
std::os::unix::fs::FileTypeExt::is_socket(self)
85+
cap_primitives::fs::FileTypeExt::is_socket(self)
8686
}
8787
}
8888

cap-primitives/src/fs/file_type.rs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,23 @@ impl FileType {
8484
}
8585
}
8686

87-
#[cfg(unix)]
88-
impl std::os::unix::fs::FileTypeExt for FileType {
87+
/// Unix-specific extensions for [`FileType`].
88+
///
89+
/// This corresponds to [`std::os::unix::fs::FileTypeExt`].
90+
#[cfg(any(unix, target_os = "vxworks"))]
91+
pub trait FileTypeExt {
92+
/// Returns `true` if this file type is a block device.
93+
fn is_block_device(&self) -> bool;
94+
/// Returns `true` if this file type is a character device.
95+
fn is_char_device(&self) -> bool;
96+
/// Returns `true` if this file type is a fifo.
97+
fn is_fifo(&self) -> bool;
98+
/// Returns `true` if this file type is a socket.
99+
fn is_socket(&self) -> bool;
100+
}
101+
102+
#[cfg(any(unix, target_os = "vxworks"))]
103+
impl FileTypeExt for FileType {
89104
#[inline]
90105
fn is_block_device(&self) -> bool {
91106
self.0 == Inner::Ext(ImplFileTypeExt::block_device())
@@ -107,31 +122,19 @@ impl std::os::unix::fs::FileTypeExt for FileType {
107122
}
108123
}
109124

110-
#[cfg(target_os = "vxworks")]
111-
impl std::os::vxworks::fs::FileTypeExt for FileType {
112-
#[inline]
113-
fn is_block_device(&self) -> bool {
114-
self.0 == Inner::Ext(FileTypeExt::BlockDevice)
115-
}
116-
117-
#[inline]
118-
fn is_char_device(&self) -> bool {
119-
self.0 == Inner::Ext(FileTypeExt::CharDevice)
120-
}
121-
122-
#[inline]
123-
fn is_fifo(&self) -> bool {
124-
self.0 == Inner::Ext(FileTypeExt::Fifo)
125-
}
126-
127-
#[inline]
128-
fn is_socket(&self) -> bool {
129-
self.0 == Inner::Ext(FileTypeExt::Socket)
130-
}
125+
/// Windows-specific extensions for [`FileType`].
126+
///
127+
/// This corresponds to [`std::os::windows::fs::FileTypeExt`].
128+
#[cfg(all(windows, windows_file_type_ext))]
129+
pub trait FileTypeExt {
130+
/// Returns `true` if this file type is a symbolic link that is also a directory.
131+
fn is_symlink_dir(&self) -> bool;
132+
/// Returns `true` if this file type is a symbolic link that is also a file.
133+
fn is_symlink_file(&self) -> bool;
131134
}
132135

133136
#[cfg(all(windows, windows_file_type_ext))]
134-
impl std::os::windows::fs::FileTypeExt for FileType {
137+
impl FileTypeExt for FileType {
135138
#[inline]
136139
fn is_symlink_dir(&self) -> bool {
137140
self.0 == Inner::Ext(FileTypeExt::symlink_dir())

cap-primitives/src/fs/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ pub use dir_entry::DirEntry;
6666
pub use dir_entry::_WindowsDirEntryExt;
6767
pub use dir_options::DirOptions;
6868
pub use file_type::FileType;
69+
#[cfg(any(unix, target_os = "vxworks", all(windows, windows_file_type_ext)))]
70+
pub use file_type::FileTypeExt;
6971
#[cfg(windows)]
7072
pub use file_type::_WindowsFileTypeExt;
7173
pub use follow_symlinks::FollowSymlinks;

cap-std/src/fs/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,3 +34,7 @@ pub use read_dir::ReadDir;
3434

3535
// Re-export types from `cap_primitives`.
3636
pub use cap_primitives::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};
37+
38+
// Re-export conditional types from `cap_primitives`.
39+
#[cfg(any(unix, target_os = "vxworks", all(windows, windows_file_type_ext)))]
40+
pub use cap_primitives::fs::FileTypeExt;

cap-std/src/fs_utf8/mod.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,10 @@ pub use read_dir::ReadDir;
2424
// Re-export things from `cap_std::fs` that we can use as-is.
2525
pub use crate::fs::{DirBuilder, FileType, Metadata, OpenOptions, Permissions};
2626

27+
// Re-export conditional types from `cap_primitives`.
28+
#[cfg(any(unix, target_os = "vxworks", all(windows, windows_file_type_ext)))]
29+
pub use cap_primitives::fs::FileTypeExt;
30+
2731
// Re-export `camino` to make it easy for users to depend on the same
2832
// version we do, because we use its types in our public API.
2933
pub use camino;

tests/fs_additional.rs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -913,17 +913,22 @@ fn check_metadata(std: &std::fs::Metadata, cap: &cap_std::fs::Metadata) {
913913
assert_eq!(std.file_type().is_symlink(), cap.file_type().is_symlink());
914914
#[cfg(unix)]
915915
{
916-
use std::os::unix::fs::FileTypeExt;
917916
assert_eq!(
918-
std.file_type().is_block_device(),
919-
cap.file_type().is_block_device()
917+
std::os::unix::fs::FileTypeExt::is_block_device(&std.file_type()),
918+
cap_std::fs::FileTypeExt::is_block_device(&cap.file_type())
920919
);
921920
assert_eq!(
922-
std.file_type().is_char_device(),
923-
cap.file_type().is_char_device()
921+
std::os::unix::fs::FileTypeExt::is_char_device(&std.file_type()),
922+
cap_std::fs::FileTypeExt::is_char_device(&cap.file_type())
923+
);
924+
assert_eq!(
925+
std::os::unix::fs::FileTypeExt::is_fifo(&std.file_type()),
926+
cap_std::fs::FileTypeExt::is_fifo(&cap.file_type())
927+
);
928+
assert_eq!(
929+
std::os::unix::fs::FileTypeExt::is_socket(&std.file_type()),
930+
cap_std::fs::FileTypeExt::is_socket(&cap.file_type())
924931
);
925-
assert_eq!(std.file_type().is_fifo(), cap.file_type().is_fifo());
926-
assert_eq!(std.file_type().is_socket(), cap.file_type().is_socket());
927932
}
928933

929934
assert_eq!(std.len(), cap.len());

0 commit comments

Comments
 (0)