wasmtime_wasi/p2/host/filesystem/
sync.rs

1use crate::filesystem::WasiFilesystemCtxView;
2use crate::p2::bindings::filesystem::types as async_filesystem;
3use crate::p2::bindings::sync::filesystem::types as sync_filesystem;
4use crate::p2::bindings::sync::io::streams;
5use crate::p2::{FsError, FsResult};
6use crate::runtime::in_tokio;
7use wasmtime::component::Resource;
8
9impl sync_filesystem::Host for WasiFilesystemCtxView<'_> {
10    fn convert_error_code(&mut self, err: FsError) -> anyhow::Result<sync_filesystem::ErrorCode> {
11        Ok(async_filesystem::Host::convert_error_code(self, err)?.into())
12    }
13
14    fn filesystem_error_code(
15        &mut self,
16        err: Resource<streams::Error>,
17    ) -> anyhow::Result<Option<sync_filesystem::ErrorCode>> {
18        Ok(async_filesystem::Host::filesystem_error_code(self, err)?.map(|e| e.into()))
19    }
20}
21
22impl sync_filesystem::HostDescriptor for WasiFilesystemCtxView<'_> {
23    fn advise(
24        &mut self,
25        fd: Resource<sync_filesystem::Descriptor>,
26        offset: sync_filesystem::Filesize,
27        len: sync_filesystem::Filesize,
28        advice: sync_filesystem::Advice,
29    ) -> FsResult<()> {
30        in_tokio(async {
31            async_filesystem::HostDescriptor::advise(self, fd, offset, len, advice.into()).await
32        })
33    }
34
35    fn sync_data(&mut self, fd: Resource<sync_filesystem::Descriptor>) -> FsResult<()> {
36        in_tokio(async { async_filesystem::HostDescriptor::sync_data(self, fd).await })
37    }
38
39    fn get_flags(
40        &mut self,
41        fd: Resource<sync_filesystem::Descriptor>,
42    ) -> FsResult<sync_filesystem::DescriptorFlags> {
43        Ok(in_tokio(async { async_filesystem::HostDescriptor::get_flags(self, fd).await })?.into())
44    }
45
46    fn get_type(
47        &mut self,
48        fd: Resource<sync_filesystem::Descriptor>,
49    ) -> FsResult<sync_filesystem::DescriptorType> {
50        Ok(in_tokio(async { async_filesystem::HostDescriptor::get_type(self, fd).await })?.into())
51    }
52
53    fn set_size(
54        &mut self,
55        fd: Resource<sync_filesystem::Descriptor>,
56        size: sync_filesystem::Filesize,
57    ) -> FsResult<()> {
58        in_tokio(async { async_filesystem::HostDescriptor::set_size(self, fd, size).await })
59    }
60
61    fn set_times(
62        &mut self,
63        fd: Resource<sync_filesystem::Descriptor>,
64        atim: sync_filesystem::NewTimestamp,
65        mtim: sync_filesystem::NewTimestamp,
66    ) -> FsResult<()> {
67        in_tokio(async {
68            async_filesystem::HostDescriptor::set_times(self, fd, atim.into(), mtim.into()).await
69        })
70    }
71
72    fn read(
73        &mut self,
74        fd: Resource<sync_filesystem::Descriptor>,
75        len: sync_filesystem::Filesize,
76        offset: sync_filesystem::Filesize,
77    ) -> FsResult<(Vec<u8>, bool)> {
78        in_tokio(async { async_filesystem::HostDescriptor::read(self, fd, len, offset).await })
79    }
80
81    fn write(
82        &mut self,
83        fd: Resource<sync_filesystem::Descriptor>,
84        buf: Vec<u8>,
85        offset: sync_filesystem::Filesize,
86    ) -> FsResult<sync_filesystem::Filesize> {
87        in_tokio(async { async_filesystem::HostDescriptor::write(self, fd, buf, offset).await })
88    }
89
90    fn read_directory(
91        &mut self,
92        fd: Resource<sync_filesystem::Descriptor>,
93    ) -> FsResult<Resource<sync_filesystem::DirectoryEntryStream>> {
94        in_tokio(async { async_filesystem::HostDescriptor::read_directory(self, fd).await })
95    }
96
97    fn sync(&mut self, fd: Resource<sync_filesystem::Descriptor>) -> FsResult<()> {
98        in_tokio(async { async_filesystem::HostDescriptor::sync(self, fd).await })
99    }
100
101    fn create_directory_at(
102        &mut self,
103        fd: Resource<sync_filesystem::Descriptor>,
104        path: String,
105    ) -> FsResult<()> {
106        in_tokio(async {
107            async_filesystem::HostDescriptor::create_directory_at(self, fd, path).await
108        })
109    }
110
111    fn stat(
112        &mut self,
113        fd: Resource<sync_filesystem::Descriptor>,
114    ) -> FsResult<sync_filesystem::DescriptorStat> {
115        Ok(in_tokio(async { async_filesystem::HostDescriptor::stat(self, fd).await })?.into())
116    }
117
118    fn stat_at(
119        &mut self,
120        fd: Resource<sync_filesystem::Descriptor>,
121        path_flags: sync_filesystem::PathFlags,
122        path: String,
123    ) -> FsResult<sync_filesystem::DescriptorStat> {
124        Ok(in_tokio(async {
125            async_filesystem::HostDescriptor::stat_at(self, fd, path_flags.into(), path).await
126        })?
127        .into())
128    }
129
130    fn set_times_at(
131        &mut self,
132        fd: Resource<sync_filesystem::Descriptor>,
133        path_flags: sync_filesystem::PathFlags,
134        path: String,
135        atim: sync_filesystem::NewTimestamp,
136        mtim: sync_filesystem::NewTimestamp,
137    ) -> FsResult<()> {
138        in_tokio(async {
139            async_filesystem::HostDescriptor::set_times_at(
140                self,
141                fd,
142                path_flags.into(),
143                path,
144                atim.into(),
145                mtim.into(),
146            )
147            .await
148        })
149    }
150
151    fn link_at(
152        &mut self,
153        fd: Resource<sync_filesystem::Descriptor>,
154        // TODO delete the path flags from this function
155        old_path_flags: sync_filesystem::PathFlags,
156        old_path: String,
157        new_descriptor: Resource<sync_filesystem::Descriptor>,
158        new_path: String,
159    ) -> FsResult<()> {
160        in_tokio(async {
161            async_filesystem::HostDescriptor::link_at(
162                self,
163                fd,
164                old_path_flags.into(),
165                old_path,
166                new_descriptor,
167                new_path,
168            )
169            .await
170        })
171    }
172
173    fn open_at(
174        &mut self,
175        fd: Resource<sync_filesystem::Descriptor>,
176        path_flags: sync_filesystem::PathFlags,
177        path: String,
178        oflags: sync_filesystem::OpenFlags,
179        flags: sync_filesystem::DescriptorFlags,
180    ) -> FsResult<Resource<sync_filesystem::Descriptor>> {
181        in_tokio(async {
182            async_filesystem::HostDescriptor::open_at(
183                self,
184                fd,
185                path_flags.into(),
186                path,
187                oflags.into(),
188                flags.into(),
189            )
190            .await
191        })
192    }
193
194    fn drop(&mut self, fd: Resource<sync_filesystem::Descriptor>) -> anyhow::Result<()> {
195        async_filesystem::HostDescriptor::drop(self, fd)
196    }
197
198    fn readlink_at(
199        &mut self,
200        fd: Resource<sync_filesystem::Descriptor>,
201        path: String,
202    ) -> FsResult<String> {
203        in_tokio(async { async_filesystem::HostDescriptor::readlink_at(self, fd, path).await })
204    }
205
206    fn remove_directory_at(
207        &mut self,
208        fd: Resource<sync_filesystem::Descriptor>,
209        path: String,
210    ) -> FsResult<()> {
211        in_tokio(async {
212            async_filesystem::HostDescriptor::remove_directory_at(self, fd, path).await
213        })
214    }
215
216    fn rename_at(
217        &mut self,
218        fd: Resource<sync_filesystem::Descriptor>,
219        old_path: String,
220        new_fd: Resource<sync_filesystem::Descriptor>,
221        new_path: String,
222    ) -> FsResult<()> {
223        in_tokio(async {
224            async_filesystem::HostDescriptor::rename_at(self, fd, old_path, new_fd, new_path).await
225        })
226    }
227
228    fn symlink_at(
229        &mut self,
230        fd: Resource<sync_filesystem::Descriptor>,
231        src_path: String,
232        dest_path: String,
233    ) -> FsResult<()> {
234        in_tokio(async {
235            async_filesystem::HostDescriptor::symlink_at(self, fd, src_path, dest_path).await
236        })
237    }
238
239    fn unlink_file_at(
240        &mut self,
241        fd: Resource<sync_filesystem::Descriptor>,
242        path: String,
243    ) -> FsResult<()> {
244        in_tokio(async { async_filesystem::HostDescriptor::unlink_file_at(self, fd, path).await })
245    }
246
247    fn read_via_stream(
248        &mut self,
249        fd: Resource<sync_filesystem::Descriptor>,
250        offset: sync_filesystem::Filesize,
251    ) -> FsResult<Resource<streams::InputStream>> {
252        Ok(async_filesystem::HostDescriptor::read_via_stream(
253            self, fd, offset,
254        )?)
255    }
256
257    fn write_via_stream(
258        &mut self,
259        fd: Resource<sync_filesystem::Descriptor>,
260        offset: sync_filesystem::Filesize,
261    ) -> FsResult<Resource<streams::OutputStream>> {
262        Ok(async_filesystem::HostDescriptor::write_via_stream(
263            self, fd, offset,
264        )?)
265    }
266
267    fn append_via_stream(
268        &mut self,
269        fd: Resource<sync_filesystem::Descriptor>,
270    ) -> FsResult<Resource<streams::OutputStream>> {
271        Ok(async_filesystem::HostDescriptor::append_via_stream(
272            self, fd,
273        )?)
274    }
275
276    fn is_same_object(
277        &mut self,
278        a: Resource<sync_filesystem::Descriptor>,
279        b: Resource<sync_filesystem::Descriptor>,
280    ) -> anyhow::Result<bool> {
281        in_tokio(async { async_filesystem::HostDescriptor::is_same_object(self, a, b).await })
282    }
283    fn metadata_hash(
284        &mut self,
285        fd: Resource<sync_filesystem::Descriptor>,
286    ) -> FsResult<sync_filesystem::MetadataHashValue> {
287        Ok(
288            in_tokio(async { async_filesystem::HostDescriptor::metadata_hash(self, fd).await })?
289                .into(),
290        )
291    }
292    fn metadata_hash_at(
293        &mut self,
294        fd: Resource<sync_filesystem::Descriptor>,
295        path_flags: sync_filesystem::PathFlags,
296        path: String,
297    ) -> FsResult<sync_filesystem::MetadataHashValue> {
298        Ok(in_tokio(async {
299            async_filesystem::HostDescriptor::metadata_hash_at(self, fd, path_flags.into(), path)
300                .await
301        })?
302        .into())
303    }
304}
305
306impl sync_filesystem::HostDirectoryEntryStream for WasiFilesystemCtxView<'_> {
307    fn read_directory_entry(
308        &mut self,
309        stream: Resource<sync_filesystem::DirectoryEntryStream>,
310    ) -> FsResult<Option<sync_filesystem::DirectoryEntry>> {
311        Ok(in_tokio(async {
312            async_filesystem::HostDirectoryEntryStream::read_directory_entry(self, stream).await
313        })?
314        .map(|e| e.into()))
315    }
316
317    fn drop(
318        &mut self,
319        stream: Resource<sync_filesystem::DirectoryEntryStream>,
320    ) -> anyhow::Result<()> {
321        async_filesystem::HostDirectoryEntryStream::drop(self, stream)
322    }
323}
324
325impl From<async_filesystem::ErrorCode> for sync_filesystem::ErrorCode {
326    fn from(other: async_filesystem::ErrorCode) -> Self {
327        use async_filesystem::ErrorCode;
328        match other {
329            ErrorCode::Access => Self::Access,
330            ErrorCode::WouldBlock => Self::WouldBlock,
331            ErrorCode::Already => Self::Already,
332            ErrorCode::BadDescriptor => Self::BadDescriptor,
333            ErrorCode::Busy => Self::Busy,
334            ErrorCode::Deadlock => Self::Deadlock,
335            ErrorCode::Quota => Self::Quota,
336            ErrorCode::Exist => Self::Exist,
337            ErrorCode::FileTooLarge => Self::FileTooLarge,
338            ErrorCode::IllegalByteSequence => Self::IllegalByteSequence,
339            ErrorCode::InProgress => Self::InProgress,
340            ErrorCode::Interrupted => Self::Interrupted,
341            ErrorCode::Invalid => Self::Invalid,
342            ErrorCode::Io => Self::Io,
343            ErrorCode::IsDirectory => Self::IsDirectory,
344            ErrorCode::Loop => Self::Loop,
345            ErrorCode::TooManyLinks => Self::TooManyLinks,
346            ErrorCode::MessageSize => Self::MessageSize,
347            ErrorCode::NameTooLong => Self::NameTooLong,
348            ErrorCode::NoDevice => Self::NoDevice,
349            ErrorCode::NoEntry => Self::NoEntry,
350            ErrorCode::NoLock => Self::NoLock,
351            ErrorCode::InsufficientMemory => Self::InsufficientMemory,
352            ErrorCode::InsufficientSpace => Self::InsufficientSpace,
353            ErrorCode::NotDirectory => Self::NotDirectory,
354            ErrorCode::NotEmpty => Self::NotEmpty,
355            ErrorCode::NotRecoverable => Self::NotRecoverable,
356            ErrorCode::Unsupported => Self::Unsupported,
357            ErrorCode::NoTty => Self::NoTty,
358            ErrorCode::NoSuchDevice => Self::NoSuchDevice,
359            ErrorCode::Overflow => Self::Overflow,
360            ErrorCode::NotPermitted => Self::NotPermitted,
361            ErrorCode::Pipe => Self::Pipe,
362            ErrorCode::ReadOnly => Self::ReadOnly,
363            ErrorCode::InvalidSeek => Self::InvalidSeek,
364            ErrorCode::TextFileBusy => Self::TextFileBusy,
365            ErrorCode::CrossDevice => Self::CrossDevice,
366        }
367    }
368}
369
370impl From<sync_filesystem::Advice> for async_filesystem::Advice {
371    fn from(other: sync_filesystem::Advice) -> Self {
372        use sync_filesystem::Advice;
373        match other {
374            Advice::Normal => Self::Normal,
375            Advice::Sequential => Self::Sequential,
376            Advice::Random => Self::Random,
377            Advice::WillNeed => Self::WillNeed,
378            Advice::DontNeed => Self::DontNeed,
379            Advice::NoReuse => Self::NoReuse,
380        }
381    }
382}
383
384impl From<async_filesystem::DescriptorFlags> for sync_filesystem::DescriptorFlags {
385    fn from(other: async_filesystem::DescriptorFlags) -> Self {
386        let mut out = Self::empty();
387        if other.contains(async_filesystem::DescriptorFlags::READ) {
388            out |= Self::READ;
389        }
390        if other.contains(async_filesystem::DescriptorFlags::WRITE) {
391            out |= Self::WRITE;
392        }
393        if other.contains(async_filesystem::DescriptorFlags::FILE_INTEGRITY_SYNC) {
394            out |= Self::FILE_INTEGRITY_SYNC;
395        }
396        if other.contains(async_filesystem::DescriptorFlags::DATA_INTEGRITY_SYNC) {
397            out |= Self::DATA_INTEGRITY_SYNC;
398        }
399        if other.contains(async_filesystem::DescriptorFlags::REQUESTED_WRITE_SYNC) {
400            out |= Self::REQUESTED_WRITE_SYNC;
401        }
402        if other.contains(async_filesystem::DescriptorFlags::MUTATE_DIRECTORY) {
403            out |= Self::MUTATE_DIRECTORY;
404        }
405        out
406    }
407}
408
409impl From<async_filesystem::DescriptorType> for sync_filesystem::DescriptorType {
410    fn from(other: async_filesystem::DescriptorType) -> Self {
411        use async_filesystem::DescriptorType;
412        match other {
413            DescriptorType::RegularFile => Self::RegularFile,
414            DescriptorType::Directory => Self::Directory,
415            DescriptorType::BlockDevice => Self::BlockDevice,
416            DescriptorType::CharacterDevice => Self::CharacterDevice,
417            DescriptorType::Fifo => Self::Fifo,
418            DescriptorType::Socket => Self::Socket,
419            DescriptorType::SymbolicLink => Self::SymbolicLink,
420            DescriptorType::Unknown => Self::Unknown,
421        }
422    }
423}
424
425impl From<async_filesystem::DirectoryEntry> for sync_filesystem::DirectoryEntry {
426    fn from(other: async_filesystem::DirectoryEntry) -> Self {
427        Self {
428            type_: other.type_.into(),
429            name: other.name,
430        }
431    }
432}
433
434impl From<async_filesystem::DescriptorStat> for sync_filesystem::DescriptorStat {
435    fn from(other: async_filesystem::DescriptorStat) -> Self {
436        Self {
437            type_: other.type_.into(),
438            link_count: other.link_count,
439            size: other.size,
440            data_access_timestamp: other.data_access_timestamp,
441            data_modification_timestamp: other.data_modification_timestamp,
442            status_change_timestamp: other.status_change_timestamp,
443        }
444    }
445}
446
447impl From<sync_filesystem::PathFlags> for async_filesystem::PathFlags {
448    fn from(other: sync_filesystem::PathFlags) -> Self {
449        let mut out = Self::empty();
450        if other.contains(sync_filesystem::PathFlags::SYMLINK_FOLLOW) {
451            out |= Self::SYMLINK_FOLLOW;
452        }
453        out
454    }
455}
456
457impl From<sync_filesystem::NewTimestamp> for async_filesystem::NewTimestamp {
458    fn from(other: sync_filesystem::NewTimestamp) -> Self {
459        use sync_filesystem::NewTimestamp;
460        match other {
461            NewTimestamp::NoChange => Self::NoChange,
462            NewTimestamp::Now => Self::Now,
463            NewTimestamp::Timestamp(datetime) => Self::Timestamp(datetime),
464        }
465    }
466}
467
468impl From<sync_filesystem::OpenFlags> for async_filesystem::OpenFlags {
469    fn from(other: sync_filesystem::OpenFlags) -> Self {
470        let mut out = Self::empty();
471        if other.contains(sync_filesystem::OpenFlags::CREATE) {
472            out |= Self::CREATE;
473        }
474        if other.contains(sync_filesystem::OpenFlags::DIRECTORY) {
475            out |= Self::DIRECTORY;
476        }
477        if other.contains(sync_filesystem::OpenFlags::EXCLUSIVE) {
478            out |= Self::EXCLUSIVE;
479        }
480        if other.contains(sync_filesystem::OpenFlags::TRUNCATE) {
481            out |= Self::TRUNCATE;
482        }
483        out
484    }
485}
486impl From<sync_filesystem::DescriptorFlags> for async_filesystem::DescriptorFlags {
487    fn from(other: sync_filesystem::DescriptorFlags) -> Self {
488        let mut out = Self::empty();
489        if other.contains(sync_filesystem::DescriptorFlags::READ) {
490            out |= Self::READ;
491        }
492        if other.contains(sync_filesystem::DescriptorFlags::WRITE) {
493            out |= Self::WRITE;
494        }
495        if other.contains(sync_filesystem::DescriptorFlags::FILE_INTEGRITY_SYNC) {
496            out |= Self::FILE_INTEGRITY_SYNC;
497        }
498        if other.contains(sync_filesystem::DescriptorFlags::DATA_INTEGRITY_SYNC) {
499            out |= Self::DATA_INTEGRITY_SYNC;
500        }
501        if other.contains(sync_filesystem::DescriptorFlags::REQUESTED_WRITE_SYNC) {
502            out |= Self::REQUESTED_WRITE_SYNC;
503        }
504        if other.contains(sync_filesystem::DescriptorFlags::MUTATE_DIRECTORY) {
505            out |= Self::MUTATE_DIRECTORY;
506        }
507        out
508    }
509}
510impl From<async_filesystem::MetadataHashValue> for sync_filesystem::MetadataHashValue {
511    fn from(other: async_filesystem::MetadataHashValue) -> Self {
512        Self {
513            lower: other.lower,
514            upper: other.upper,
515        }
516    }
517}