1use crate::{DirView, ViewKind};
2use cap_std::fs::{DirEntry, File, FileType, Metadata, OpenOptions};
3#[cfg(not(windows))]
4use rustix::fs::DirEntryExt;
5use std::ffi::OsString;
6use std::{fmt, io};
7
8pub struct DirEntryView {
23 pub(crate) entry: DirEntry,
24 pub(crate) view_kind: ViewKind,
25}
26
27impl DirEntryView {
28 #[inline]
30 pub fn open(&self) -> io::Result<File> {
31 self.entry.open()
32 }
33
34 #[inline]
36 pub fn open_with(&self, options: &OpenOptions) -> io::Result<File> {
37 let mut options = options.clone();
39 match self.view_kind {
40 ViewKind::Full => {}
41 ViewKind::Readonly => {
42 options.append(false);
44 options.truncate(false);
45 options.write(false);
46 options.create(false);
47 options.create_new(false);
48 }
49 }
50 self.entry.open_with(&options)
51 }
52
53 #[inline]
55 pub fn open_dir(&self) -> io::Result<DirView> {
56 Ok(DirView {
57 dir: self.entry.open_dir()?,
58 view_kind: self.view_kind,
59 })
60 }
61
62 #[inline]
64 pub fn remove_file(&self) -> io::Result<()> {
65 self.check_mutation()?;
66 self.entry.remove_file()
67 }
68
69 #[inline]
71 pub fn remove_dir(&self) -> io::Result<()> {
72 self.check_mutation()?;
73 self.entry.remove_dir()
74 }
75
76 #[inline]
80 pub fn metadata(&self) -> io::Result<Metadata> {
81 self.entry.metadata()
82 }
83
84 #[inline]
88 pub fn file_type(&self) -> io::Result<FileType> {
89 self.entry.file_type()
90 }
91
92 #[inline]
97 pub fn file_name(&self) -> OsString {
98 self.entry.file_name()
99 }
100
101 fn check_mutation(&self) -> io::Result<()> {
102 match self.view_kind {
103 ViewKind::Full => Ok(()),
104 ViewKind::Readonly => Err(Self::readonly()),
105 }
106 }
107
108 fn readonly() -> io::Error {
109 io::Error::new(
110 io::ErrorKind::PermissionDenied,
111 "attempt to modify a directory tree through a read-only `DirView`",
112 )
113 }
114}
115
116#[cfg(not(windows))]
117impl DirEntryExt for DirEntryView {
118 #[inline]
119 fn ino(&self) -> u64 {
120 self.entry.ino()
121 }
122}
123
124#[cfg(windows)]
125#[doc(hidden)]
126impl cap_primitives::fs::_WindowsDirEntryExt for DirEntryView {
127 #[inline]
128 fn full_metadata(&self) -> io::Result<Metadata> {
129 cap_primitives::fs::_WindowsDirEntryExt::full_metadata(&self.entry)
130 }
131}
132
133impl fmt::Debug for DirEntryView {
134 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
135 self.entry.fmt(f)
136 }
137}
138
139#[cfg(feature = "cap-fs-ext")]
140impl cap_fs_ext::DirEntryExt for DirEntryView {
141 fn full_metadata(&self) -> io::Result<Metadata> {
142 cap_fs_ext::DirEntryExt::full_metadata(&self.entry)
143 }
144}