1use super::*;
2use std::path::PathBuf;
3
4pub const DEFAULT_READ_MAX_BYTES: usize = 16 * 1024 * 1024;
6
7pub const DEFAULT_READ_STREAM_CHUNK_BYTES: usize = 1024 * 1024;
9
10pub const DEFAULT_READ_ALLV_MAX_TOTAL_BYTES: usize = DEFAULT_READ_MAX_BYTES;
12
13#[derive(Clone, Copy, Debug, PartialEq, Eq)]
15pub struct StreamOptions {
16 chunk_size: std::num::NonZeroUsize,
17}
18
19impl StreamOptions {
20 pub const fn new() -> Self {
21 Self {
22 chunk_size: std::num::NonZeroUsize::new(DEFAULT_READ_STREAM_CHUNK_BYTES).unwrap(),
23 }
24 }
25
26 pub const fn chunk_size(mut self, bytes: std::num::NonZeroUsize) -> Self {
36 self.chunk_size = bytes;
37 self
38 }
39
40 pub const fn chunk_size_bytes(self) -> usize {
41 self.chunk_size.get()
42 }
43}
44
45impl Default for StreamOptions {
46 fn default() -> Self {
47 Self::new()
48 }
49}
50
51pub const DEFAULT_DIRECTORY_MAX_ENTRIES: usize = 100_000;
53
54pub const DEFAULT_DIRECTORY_MAX_PATH_BYTES: usize = 16 * 1024 * 1024;
56
57pub const DEFAULT_WALK_MAX_DEPTH: usize = 128;
59
60#[repr(transparent)]
64#[derive(Clone, Copy, Debug, PartialEq, Eq)]
65pub struct DepthLimit(std::num::NonZeroU8);
66
67impl DepthLimit {
68 pub const fn new(depth: usize) -> Self {
70 let encoded = if depth <= 200 { (depth + 1) as u8 } else { 202 };
71 Self(std::num::NonZeroU8::new(encoded).expect("depth encoding is nonzero"))
72 }
73 pub const fn unlimited() -> Self {
75 Self::new(usize::MAX)
76 }
77 pub const fn get(self) -> usize {
79 if self.is_unlimited() {
80 usize::MAX
81 } else {
82 self.0.get() as usize - 1
83 }
84 }
85 pub const fn is_unlimited(self) -> bool {
87 self.0.get() == 202
88 }
89}
90
91pub const DEFAULT_READV_MAX_TOTAL_BYTES: usize = DEFAULT_READ_MAX_BYTES;
93
94#[derive(Debug, Clone, PartialEq, Eq)]
96pub struct FsReadResult {
97 pub offset: u64,
98 pub data: Vec<u8>,
99 pub eof: bool,
100}
101
102#[derive(Debug, Clone, Copy, PartialEq, Eq)]
104pub struct ReadIntoResult {
105 pub offset: u64,
106 pub read: usize,
107 pub eof: bool,
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
114pub struct WriteResult {
115 pub offset: u64,
116 pub written: usize,
117 pub stable: bool,
118}
119
120#[derive(Debug, Clone, Copy, PartialEq, Eq)]
122pub enum StreamCompletion {
123 Complete,
124 Stopped { next_offset: u64 },
125}
126
127#[derive(Debug, Clone, Copy, PartialEq, Eq)]
129pub enum TraversalCompletion {
130 Complete,
131 Stopped,
132}
133
134#[derive(Debug, Clone, Copy, PartialEq, Eq)]
137pub struct ResourceLimits {
138 max_read_bytes: usize,
142 stream_chunk_bytes: std::num::NonZeroUsize,
144 max_directory_entries: usize,
146 max_directory_path_bytes: usize,
148 max_walk_depth: usize,
150}
151
152impl Default for ResourceLimits {
153 fn default() -> Self {
154 Self {
155 max_read_bytes: DEFAULT_READ_MAX_BYTES,
156 stream_chunk_bytes: std::num::NonZeroUsize::new(DEFAULT_READ_STREAM_CHUNK_BYTES)
157 .unwrap(),
158 max_directory_entries: crate::api::DEFAULT_DIRECTORY_MAX_ENTRIES,
159 max_directory_path_bytes: crate::api::DEFAULT_DIRECTORY_MAX_PATH_BYTES,
160 max_walk_depth: crate::api::DEFAULT_WALK_MAX_DEPTH,
161 }
162 }
163}
164
165impl ResourceLimits {
166 pub fn new() -> Self {
167 Self::default()
168 }
169 pub const fn max_read_bytes(mut self, value: usize) -> Self {
171 self.max_read_bytes = value;
172 self
173 }
174 pub const fn read_byte_limit(self) -> usize {
176 self.max_read_bytes
177 }
178 pub const fn stream_chunk_bytes(mut self, value: std::num::NonZeroUsize) -> Self {
180 self.stream_chunk_bytes = value;
181 self
182 }
183 pub const fn stream_chunk_size(self) -> usize {
185 self.stream_chunk_bytes.get()
186 }
187 pub const fn max_directory_entries(mut self, value: usize) -> Self {
189 self.max_directory_entries = value;
190 self
191 }
192 pub const fn directory_entry_limit(self) -> usize {
194 self.max_directory_entries
195 }
196 pub const fn max_directory_path_bytes(mut self, value: usize) -> Self {
198 self.max_directory_path_bytes = value;
199 self
200 }
201 pub const fn directory_path_byte_limit(self) -> usize {
203 self.max_directory_path_bytes
204 }
205 pub const fn max_walk_depth(mut self, value: usize) -> Self {
207 self.max_walk_depth = value;
208 self
209 }
210 pub const fn walk_depth_limit(self) -> usize {
212 self.max_walk_depth
213 }
214
215 pub fn directory_options(self) -> ListDirOptions {
216 ListDirOptions::new()
217 .max_entries(self.max_directory_entries)
218 .max_path_bytes(self.max_directory_path_bytes)
219 }
220
221 pub fn walk_options(self) -> crate::api::ListDirOptions {
222 crate::api::ListDirOptions::new()
223 .recursive(true)
224 .max_entries(self.max_directory_entries)
225 .max_path_bytes(self.max_directory_path_bytes)
226 .max_depth(self.max_walk_depth)
227 }
228}
229
230#[derive(Clone, Debug, PartialEq, Eq)]
232pub struct DirectoryListing {
233 pub path: PathBuf,
234 pub entries: Vec<DirEntry>,
235}