wasmtime_wasi/p3/filesystem/
mod.rs1mod host;
2
3use crate::TrappableError;
4use crate::filesystem::{
5 WasiFilesystem, WasiFilesystemNamed, WasiFilesystemNamedView, WasiFilesystemView,
6};
7use crate::p3::Interface;
8use crate::p3::bindings::filesystem::{preopens, types};
9use crate::{NamedId, WasiCtxNamedView};
10use wasmtime::component::{Component, Linker};
11
12pub type FilesystemResult<T> = Result<T, FilesystemError>;
13pub type FilesystemError = TrappableError<types::ErrorCode>;
14
15pub fn add_to_linker<T>(linker: &mut Linker<T>) -> wasmtime::Result<()>
67where
68 T: WasiFilesystemView + 'static,
69{
70 types::add_to_linker::<_, WasiFilesystem>(linker, T::filesystem)?;
71 preopens::add_to_linker::<_, WasiFilesystem>(linker, T::filesystem)?;
72 Ok(())
73}
74
75pub fn add_named_to_linker<T>(
159 linker: &mut Linker<T>,
160 component: &Component,
161 mut lookup: impl FnMut(Interface, &str) -> wasmtime::Result<NamedId>,
162) -> wasmtime::Result<()>
163where
164 T: WasiFilesystemNamedView + 'static,
165{
166 use crate::p3::bindings::named_imports::wasi::filesystem::{preopens, types};
167 types::add_to_linker::<_, WasiFilesystemNamed<T>>(
168 linker,
169 component,
170 |name| lookup(Interface::FilesystemTypes, name),
171 |x| WasiCtxNamedView(x),
172 )?;
173 preopens::add_to_linker::<_, WasiFilesystemNamed<T>>(
174 linker,
175 component,
176 |name| lookup(Interface::FilesystemPreopens, name),
177 |x| WasiCtxNamedView(x),
178 )?;
179 Ok(())
180}
181
182impl<'a> From<&'a std::io::Error> for types::ErrorCode {
183 fn from(err: &'a std::io::Error) -> Self {
184 crate::filesystem::ErrorCode::from(err).into()
185 }
186}
187
188impl From<std::io::Error> for types::ErrorCode {
189 fn from(err: std::io::Error) -> Self {
190 Self::from(&err)
191 }
192}
193
194impl From<std::io::Error> for FilesystemError {
195 fn from(error: std::io::Error) -> Self {
196 types::ErrorCode::from(error).into()
197 }
198}
199
200impl From<crate::filesystem::ErrorCode> for types::ErrorCode {
201 fn from(error: crate::filesystem::ErrorCode) -> Self {
202 match error {
203 crate::filesystem::ErrorCode::Access => Self::Access,
204 crate::filesystem::ErrorCode::Already => Self::Already,
205 crate::filesystem::ErrorCode::BadDescriptor => Self::BadDescriptor,
206 crate::filesystem::ErrorCode::Busy => Self::Busy,
207 crate::filesystem::ErrorCode::Exist => Self::Exist,
208 crate::filesystem::ErrorCode::FileTooLarge => Self::FileTooLarge,
209 crate::filesystem::ErrorCode::IllegalByteSequence => Self::IllegalByteSequence,
210 crate::filesystem::ErrorCode::InProgress => Self::InProgress,
211 crate::filesystem::ErrorCode::Interrupted => Self::Interrupted,
212 crate::filesystem::ErrorCode::Invalid => Self::Invalid,
213 crate::filesystem::ErrorCode::Io => Self::Io,
214 crate::filesystem::ErrorCode::IsDirectory => Self::IsDirectory,
215 crate::filesystem::ErrorCode::Loop => Self::Loop,
216 crate::filesystem::ErrorCode::TooManyLinks => Self::TooManyLinks,
217 crate::filesystem::ErrorCode::NameTooLong => Self::NameTooLong,
218 crate::filesystem::ErrorCode::NoEntry => Self::NoEntry,
219 crate::filesystem::ErrorCode::InsufficientMemory => Self::InsufficientMemory,
220 crate::filesystem::ErrorCode::InsufficientSpace => Self::InsufficientSpace,
221 crate::filesystem::ErrorCode::NotDirectory => Self::NotDirectory,
222 crate::filesystem::ErrorCode::NotEmpty => Self::NotEmpty,
223 crate::filesystem::ErrorCode::Unsupported => Self::Unsupported,
224 crate::filesystem::ErrorCode::Overflow => Self::Overflow,
225 crate::filesystem::ErrorCode::NotPermitted => Self::NotPermitted,
226 crate::filesystem::ErrorCode::Pipe => Self::Pipe,
227 crate::filesystem::ErrorCode::InvalidSeek => Self::InvalidSeek,
228 }
229 }
230}
231
232impl From<crate::filesystem::ErrorCode> for FilesystemError {
233 fn from(error: crate::filesystem::ErrorCode) -> Self {
234 types::ErrorCode::from(error).into()
235 }
236}
237
238impl From<wasmtime::component::ResourceTableError> for FilesystemError {
239 fn from(error: wasmtime::component::ResourceTableError) -> Self {
240 Self::trap(error)
241 }
242}
243
244impl From<types::Advice> for crate::filesystem::Advice {
245 fn from(advice: types::Advice) -> Self {
246 match advice {
247 types::Advice::Normal => Self::Normal,
248 types::Advice::Sequential => Self::Sequential,
249 types::Advice::Random => Self::Random,
250 types::Advice::WillNeed => Self::WillNeed,
251 types::Advice::DontNeed => Self::DontNeed,
252 types::Advice::NoReuse => Self::NoReuse,
253 }
254 }
255}
256
257impl From<types::OpenFlags> for crate::filesystem::OpenFlags {
258 fn from(flags: types::OpenFlags) -> Self {
259 let mut out = Self::empty();
260 if flags.contains(types::OpenFlags::CREATE) {
261 out |= Self::CREATE;
262 }
263 if flags.contains(types::OpenFlags::DIRECTORY) {
264 out |= Self::DIRECTORY;
265 }
266 if flags.contains(types::OpenFlags::EXCLUSIVE) {
267 out |= Self::EXCLUSIVE;
268 }
269 if flags.contains(types::OpenFlags::TRUNCATE) {
270 out |= Self::TRUNCATE;
271 }
272 out
273 }
274}
275
276impl From<types::PathFlags> for crate::filesystem::PathFlags {
277 fn from(flags: types::PathFlags) -> Self {
278 let mut out = Self::empty();
279 if flags.contains(types::PathFlags::SYMLINK_FOLLOW) {
280 out |= Self::SYMLINK_FOLLOW;
281 }
282 out
283 }
284}
285
286impl From<crate::filesystem::DescriptorFlags> for types::DescriptorFlags {
287 fn from(flags: crate::filesystem::DescriptorFlags) -> Self {
288 let mut out = Self::empty();
289 if flags.contains(crate::filesystem::DescriptorFlags::READ) {
290 out |= Self::READ;
291 }
292 if flags.contains(crate::filesystem::DescriptorFlags::WRITE) {
293 out |= Self::WRITE;
294 }
295 if flags.contains(crate::filesystem::DescriptorFlags::FILE_INTEGRITY_SYNC) {
296 out |= Self::FILE_INTEGRITY_SYNC;
297 }
298 if flags.contains(crate::filesystem::DescriptorFlags::DATA_INTEGRITY_SYNC) {
299 out |= Self::DATA_INTEGRITY_SYNC;
300 }
301 if flags.contains(crate::filesystem::DescriptorFlags::REQUESTED_WRITE_SYNC) {
302 out |= Self::REQUESTED_WRITE_SYNC;
303 }
304 if flags.contains(crate::filesystem::DescriptorFlags::MUTATE_DIRECTORY) {
305 out |= Self::MUTATE_DIRECTORY;
306 }
307 out
308 }
309}
310
311impl From<types::DescriptorFlags> for crate::filesystem::DescriptorFlags {
312 fn from(flags: types::DescriptorFlags) -> Self {
313 let mut out = Self::empty();
314 if flags.contains(types::DescriptorFlags::READ) {
315 out |= Self::READ;
316 }
317 if flags.contains(types::DescriptorFlags::WRITE) {
318 out |= Self::WRITE;
319 }
320 if flags.contains(types::DescriptorFlags::FILE_INTEGRITY_SYNC) {
321 out |= Self::FILE_INTEGRITY_SYNC;
322 }
323 if flags.contains(types::DescriptorFlags::DATA_INTEGRITY_SYNC) {
324 out |= Self::DATA_INTEGRITY_SYNC;
325 }
326 if flags.contains(types::DescriptorFlags::REQUESTED_WRITE_SYNC) {
327 out |= Self::REQUESTED_WRITE_SYNC;
328 }
329 if flags.contains(types::DescriptorFlags::MUTATE_DIRECTORY) {
330 out |= Self::MUTATE_DIRECTORY;
331 }
332 out
333 }
334}
335
336impl From<crate::filesystem::MetadataHashValue> for types::MetadataHashValue {
337 fn from(
338 crate::filesystem::MetadataHashValue { lower, upper }: crate::filesystem::MetadataHashValue,
339 ) -> Self {
340 Self { lower, upper }
341 }
342}
343
344impl From<crate::filesystem::DescriptorStat> for types::DescriptorStat {
345 fn from(
346 crate::filesystem::DescriptorStat {
347 type_,
348 link_count,
349 size,
350 data_access_timestamp,
351 data_modification_timestamp,
352 status_change_timestamp,
353 }: crate::filesystem::DescriptorStat,
354 ) -> Self {
355 Self {
356 type_: type_.into(),
357 link_count,
358 size,
359 data_access_timestamp: data_access_timestamp.map(Into::into),
360 data_modification_timestamp: data_modification_timestamp.map(Into::into),
361 status_change_timestamp: status_change_timestamp.map(Into::into),
362 }
363 }
364}
365
366impl From<crate::filesystem::DescriptorType> for types::DescriptorType {
367 fn from(ty: crate::filesystem::DescriptorType) -> Self {
368 match ty {
369 crate::filesystem::DescriptorType::Unknown => Self::Other(None),
370 crate::filesystem::DescriptorType::BlockDevice => Self::BlockDevice,
371 crate::filesystem::DescriptorType::CharacterDevice => Self::CharacterDevice,
372 crate::filesystem::DescriptorType::Directory => Self::Directory,
373 crate::filesystem::DescriptorType::SymbolicLink => Self::SymbolicLink,
374 crate::filesystem::DescriptorType::RegularFile => Self::RegularFile,
375 }
376 }
377}
378
379impl From<crate::filesystem::primitives::FileType> for types::DescriptorType {
380 fn from(ft: crate::filesystem::primitives::FileType) -> Self {
381 crate::filesystem::DescriptorType::from(ft).into()
382 }
383}