Skip to content

Commit 949f251

Browse files
authored
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 de73972 commit 949f251

File tree

17 files changed

+97
-70
lines changed

17 files changed

+97
-70
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: 36 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
//! The `FileType` struct.
22
3-
use crate::fs::FileTypeExt;
3+
use crate::fs::ImplFileTypeExt;
44

55
/// `FileType`'s inner state.
66
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
@@ -15,7 +15,7 @@ enum Inner {
1515
Unknown,
1616

1717
/// A `FileTypeExt` type.
18-
Ext(FileTypeExt),
18+
Ext(ImplFileTypeExt),
1919
}
2020

2121
/// A structure representing a type of file with accessors for each file type.
@@ -51,7 +51,7 @@ impl FileType {
5151

5252
/// Creates a `FileType` from extension type.
5353
#[inline]
54-
pub(crate) const fn ext(ext: FileTypeExt) -> Self {
54+
pub(crate) const fn ext(ext: ImplFileTypeExt) -> Self {
5555
Self(Inner::Ext(ext))
5656
}
5757

@@ -84,62 +84,65 @@ impl FileType {
8484
}
8585
}
8686

87-
#[cfg(unix)]
88-
impl std::os::unix::fs::FileTypeExt for FileType {
89-
#[inline]
90-
fn is_block_device(&self) -> bool {
91-
self.0 == Inner::Ext(crate::fs::FileTypeExt::block_device())
92-
}
93-
94-
#[inline]
95-
fn is_char_device(&self) -> bool {
96-
self.0 == Inner::Ext(FileTypeExt::char_device())
97-
}
98-
99-
#[inline]
100-
fn is_fifo(&self) -> bool {
101-
self.0 == Inner::Ext(FileTypeExt::fifo())
102-
}
103-
104-
#[inline]
105-
fn is_socket(&self) -> bool {
106-
self.0 == Inner::Ext(FileTypeExt::socket())
107-
}
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;
108100
}
109101

110-
#[cfg(target_os = "vxworks")]
111-
impl std::os::vxworks::fs::FileTypeExt for FileType {
102+
#[cfg(any(unix, target_os = "vxworks"))]
103+
impl FileTypeExt for FileType {
112104
#[inline]
113105
fn is_block_device(&self) -> bool {
114-
self.0 == Inner::Ext(FileTypeExt::BlockDevice)
106+
self.0 == Inner::Ext(ImplFileTypeExt::block_device())
115107
}
116108

117109
#[inline]
118110
fn is_char_device(&self) -> bool {
119-
self.0 == Inner::Ext(FileTypeExt::CharDevice)
111+
self.0 == Inner::Ext(ImplFileTypeExt::char_device())
120112
}
121113

122114
#[inline]
123115
fn is_fifo(&self) -> bool {
124-
self.0 == Inner::Ext(FileTypeExt::Fifo)
116+
self.0 == Inner::Ext(ImplFileTypeExt::fifo())
125117
}
126118

127119
#[inline]
128120
fn is_socket(&self) -> bool {
129-
self.0 == Inner::Ext(FileTypeExt::Socket)
121+
self.0 == Inner::Ext(ImplFileTypeExt::socket())
130122
}
131123
}
132124

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;
134+
}
135+
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 {
137-
self.0 == Inner::Ext(FileTypeExt::symlink_dir())
140+
self.0 == Inner::Ext(ImplFileTypeExt::symlink_dir())
138141
}
139142

140143
#[inline]
141144
fn is_symlink_file(&self) -> bool {
142-
self.0 == Inner::Ext(FileTypeExt::symlink_file())
145+
self.0 == Inner::Ext(ImplFileTypeExt::symlink_file())
143146
}
144147
}
145148

cap-primitives/src/fs/metadata.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::fs::{FileType, FileTypeExt, MetadataExt, Permissions};
1+
use crate::fs::{FileType, ImplFileTypeExt, MetadataExt, Permissions};
22
use crate::time::SystemTime;
33
use std::{fs, io};
44

@@ -28,7 +28,7 @@ impl Metadata {
2828
pub fn from_file(file: &fs::File) -> io::Result<Self> {
2929
let std = file.metadata()?;
3030
let ext = MetadataExt::from(file, &std)?;
31-
let file_type = FileTypeExt::from(file, &std)?;
31+
let file_type = ImplFileTypeExt::from(file, &std)?;
3232
Ok(Self::from_parts(std, ext, file_type))
3333
}
3434

@@ -42,7 +42,7 @@ impl Metadata {
4242
#[inline]
4343
pub fn from_just_metadata(std: fs::Metadata) -> Self {
4444
let ext = MetadataExt::from_just_metadata(&std);
45-
let file_type = FileTypeExt::from_just_metadata(&std);
45+
let file_type = ImplFileTypeExt::from_just_metadata(&std);
4646
Self::from_parts(std, ext, file_type)
4747
}
4848

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-primitives/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![deny(missing_docs)]
44
#![deny(unsafe_code)]
5+
#![allow(stable_features)]
56
#![cfg_attr(target_os = "wasi", feature(wasi_ext))]
67
#![cfg_attr(all(windows, windows_by_handle), feature(windows_by_handle))]
78
#![cfg_attr(all(windows, windows_file_type_ext), feature(windows_file_type_ext))]

cap-primitives/src/rustix/fs/dir_entry_inner.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
use crate::fs::{
2-
FileType, FileTypeExt, FollowSymlinks, Metadata, OpenOptions, ReadDir, ReadDirInner,
2+
FileType, FollowSymlinks, ImplFileTypeExt, Metadata, OpenOptions, ReadDir, ReadDirInner,
33
};
44
use rustix::fs::DirEntry;
55
use std::ffi::{OsStr, OsString};
@@ -46,13 +46,13 @@ impl DirEntryInner {
4646
Ok(match self.rustix.file_type() {
4747
rustix::fs::FileType::Directory => FileType::dir(),
4848
rustix::fs::FileType::RegularFile => FileType::file(),
49-
rustix::fs::FileType::Symlink => FileType::ext(FileTypeExt::symlink()),
49+
rustix::fs::FileType::Symlink => FileType::ext(ImplFileTypeExt::symlink()),
5050
#[cfg(not(target_os = "wasi"))]
51-
rustix::fs::FileType::Fifo => FileType::ext(FileTypeExt::fifo()),
51+
rustix::fs::FileType::Fifo => FileType::ext(ImplFileTypeExt::fifo()),
5252
#[cfg(not(target_os = "wasi"))]
53-
rustix::fs::FileType::Socket => FileType::ext(FileTypeExt::socket()),
54-
rustix::fs::FileType::CharacterDevice => FileType::ext(FileTypeExt::char_device()),
55-
rustix::fs::FileType::BlockDevice => FileType::ext(FileTypeExt::block_device()),
53+
rustix::fs::FileType::Socket => FileType::ext(ImplFileTypeExt::socket()),
54+
rustix::fs::FileType::CharacterDevice => FileType::ext(ImplFileTypeExt::char_device()),
55+
rustix::fs::FileType::BlockDevice => FileType::ext(ImplFileTypeExt::block_device()),
5656
rustix::fs::FileType::Unknown => FileType::unknown(),
5757
})
5858
}

cap-primitives/src/rustix/fs/file_type_ext.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,17 @@ use crate::fs::FileType;
22
use rustix::fs::RawMode;
33
use std::{fs, io};
44

5+
/// A type that implements `FileTypeExt` for this platform.
56
#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
6-
pub(crate) enum FileTypeExt {
7+
pub(crate) enum ImplFileTypeExt {
78
Symlink,
89
BlockDevice,
910
CharDevice,
1011
Fifo,
1112
Socket,
1213
}
1314

14-
impl FileTypeExt {
15+
impl ImplFileTypeExt {
1516
/// Constructs a new instance of `FileType` from the given
1617
/// [`std::fs::File`] and [`std::fs::FileType`].
1718
#[inline]

cap-primitives/src/rustix/fs/metadata_ext.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#![allow(clippy::useless_conversion)]
22

3-
use crate::fs::{FileTypeExt, Metadata, PermissionsExt};
3+
use crate::fs::{ImplFileTypeExt, Metadata, PermissionsExt};
44
use crate::time::{Duration, SystemClock, SystemTime};
55
#[cfg(any(target_os = "android", target_os = "linux"))]
66
use rustix::fs::{makedev, Statx, StatxFlags};
@@ -103,7 +103,7 @@ impl MetadataExt {
103103
#[inline]
104104
pub(crate) fn from_rustix(stat: Stat) -> Metadata {
105105
Metadata {
106-
file_type: FileTypeExt::from_raw_mode(stat.st_mode as RawMode),
106+
file_type: ImplFileTypeExt::from_raw_mode(stat.st_mode as RawMode),
107107
len: u64::try_from(stat.st_size).unwrap(),
108108
#[cfg(not(target_os = "wasi"))]
109109
permissions: PermissionsExt::from_raw_mode(stat.st_mode as RawMode),
@@ -223,7 +223,7 @@ impl MetadataExt {
223223
#[inline]
224224
pub(crate) fn from_rustix_statx(statx: Statx) -> Metadata {
225225
Metadata {
226-
file_type: FileTypeExt::from_raw_mode(RawMode::from(statx.stx_mode)),
226+
file_type: ImplFileTypeExt::from_raw_mode(RawMode::from(statx.stx_mode)),
227227
len: u64::try_from(statx.stx_size).unwrap(),
228228
permissions: PermissionsExt::from_raw_mode(RawMode::from(statx.stx_mode)),
229229
modified: if statx.stx_mask & StatxFlags::MTIME.bits() != 0 {

0 commit comments

Comments
 (0)