1use crate::preview0::types::Error;
7use crate::preview1::types as snapshot1_types;
8use crate::preview1::wasi_snapshot_preview1::WasiSnapshotPreview1 as Snapshot1;
9use crate::preview1::WasiP1Ctx;
10use wiggle::{GuestError, GuestMemory, GuestPtr};
11
12pub fn add_to_linker_async<T: Send>(
13 linker: &mut wasmtime::Linker<T>,
14 f: impl Fn(&mut T) -> &mut WasiP1Ctx + Copy + Send + Sync + 'static,
15) -> anyhow::Result<()> {
16 wasi_unstable::add_to_linker(linker, f)
17}
18
19pub fn add_to_linker_sync<T: Send>(
20 linker: &mut wasmtime::Linker<T>,
21 f: impl Fn(&mut T) -> &mut WasiP1Ctx + Copy + Send + Sync + 'static,
22) -> anyhow::Result<()> {
23 sync::add_wasi_unstable_to_linker(linker, f)
24}
25
26wiggle::from_witx!({
27 witx: ["$CARGO_MANIFEST_DIR/witx/preview0/wasi_unstable.witx"],
28 async: {
29 wasi_unstable::{
30 fd_advise, fd_close, fd_datasync, fd_fdstat_get, fd_filestat_get, fd_filestat_set_size,
31 fd_filestat_set_times, fd_read, fd_pread, fd_seek, fd_sync, fd_readdir, fd_write,
32 fd_pwrite, poll_oneoff, path_create_directory, path_filestat_get,
33 path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory,
34 path_rename, path_symlink, path_unlink_file
35 }
36 },
37 errors: { errno => trappable Error },
38});
39
40mod sync {
41 use anyhow::Result;
42 use std::future::Future;
43
44 wiggle::wasmtime_integration!({
45 witx: ["$CARGO_MANIFEST_DIR/witx/preview0/wasi_unstable.witx"],
46 target: super,
47 block_on[in_tokio]: {
48 wasi_unstable::{
49 fd_advise, fd_close, fd_datasync, fd_fdstat_get, fd_filestat_get, fd_filestat_set_size,
50 fd_filestat_set_times, fd_read, fd_pread, fd_seek, fd_sync, fd_readdir, fd_write,
51 fd_pwrite, poll_oneoff, path_create_directory, path_filestat_get,
52 path_filestat_set_times, path_link, path_open, path_readlink, path_remove_directory,
53 path_rename, path_symlink, path_unlink_file
54 }
55 },
56 errors: { errno => trappable Error },
57 });
58
59 fn in_tokio<F: Future>(future: F) -> Result<F::Output> {
62 Ok(crate::runtime::in_tokio(future))
63 }
64}
65
66impl wiggle::GuestErrorType for types::Errno {
67 fn success() -> Self {
68 Self::Success
69 }
70}
71
72#[wiggle::async_trait]
73impl<T: Snapshot1 + Send> wasi_unstable::WasiUnstable for T {
74 fn args_get(
75 &mut self,
76 memory: &mut GuestMemory<'_>,
77 argv: GuestPtr<GuestPtr<u8>>,
78 argv_buf: GuestPtr<u8>,
79 ) -> Result<(), Error> {
80 Snapshot1::args_get(self, memory, argv, argv_buf)?;
81 Ok(())
82 }
83
84 fn args_sizes_get(
85 &mut self,
86 memory: &mut GuestMemory<'_>,
87 ) -> Result<(types::Size, types::Size), Error> {
88 let s = Snapshot1::args_sizes_get(self, memory)?;
89 Ok(s)
90 }
91
92 fn environ_get(
93 &mut self,
94 memory: &mut GuestMemory<'_>,
95 environ: GuestPtr<GuestPtr<u8>>,
96 environ_buf: GuestPtr<u8>,
97 ) -> Result<(), Error> {
98 Snapshot1::environ_get(self, memory, environ, environ_buf)?;
99 Ok(())
100 }
101
102 fn environ_sizes_get(
103 &mut self,
104 memory: &mut GuestMemory<'_>,
105 ) -> Result<(types::Size, types::Size), Error> {
106 let s = Snapshot1::environ_sizes_get(self, memory)?;
107 Ok(s)
108 }
109
110 fn clock_res_get(
111 &mut self,
112 memory: &mut GuestMemory<'_>,
113 id: types::Clockid,
114 ) -> Result<types::Timestamp, Error> {
115 let t = Snapshot1::clock_res_get(self, memory, id.into())?;
116 Ok(t)
117 }
118
119 fn clock_time_get(
120 &mut self,
121 memory: &mut GuestMemory<'_>,
122 id: types::Clockid,
123 precision: types::Timestamp,
124 ) -> Result<types::Timestamp, Error> {
125 let t = Snapshot1::clock_time_get(self, memory, id.into(), precision)?;
126 Ok(t)
127 }
128
129 async fn fd_advise(
130 &mut self,
131 memory: &mut GuestMemory<'_>,
132 fd: types::Fd,
133 offset: types::Filesize,
134 len: types::Filesize,
135 advice: types::Advice,
136 ) -> Result<(), Error> {
137 Snapshot1::fd_advise(self, memory, fd.into(), offset, len, advice.into()).await?;
138 Ok(())
139 }
140
141 fn fd_allocate(
142 &mut self,
143 memory: &mut GuestMemory<'_>,
144 fd: types::Fd,
145 offset: types::Filesize,
146 len: types::Filesize,
147 ) -> Result<(), Error> {
148 Snapshot1::fd_allocate(self, memory, fd.into(), offset, len)?;
149 Ok(())
150 }
151
152 async fn fd_close(&mut self, memory: &mut GuestMemory<'_>, fd: types::Fd) -> Result<(), Error> {
153 Snapshot1::fd_close(self, memory, fd.into()).await?;
154 Ok(())
155 }
156
157 async fn fd_datasync(
158 &mut self,
159 memory: &mut GuestMemory<'_>,
160 fd: types::Fd,
161 ) -> Result<(), Error> {
162 Snapshot1::fd_datasync(self, memory, fd.into()).await?;
163 Ok(())
164 }
165
166 async fn fd_fdstat_get(
167 &mut self,
168 memory: &mut GuestMemory<'_>,
169 fd: types::Fd,
170 ) -> Result<types::Fdstat, Error> {
171 Ok(Snapshot1::fd_fdstat_get(self, memory, fd.into())
172 .await?
173 .into())
174 }
175
176 fn fd_fdstat_set_flags(
177 &mut self,
178 memory: &mut GuestMemory<'_>,
179 fd: types::Fd,
180 flags: types::Fdflags,
181 ) -> Result<(), Error> {
182 Snapshot1::fd_fdstat_set_flags(self, memory, fd.into(), flags.into())?;
183 Ok(())
184 }
185
186 fn fd_fdstat_set_rights(
187 &mut self,
188 memory: &mut GuestMemory<'_>,
189 fd: types::Fd,
190 fs_rights_base: types::Rights,
191 fs_rights_inheriting: types::Rights,
192 ) -> Result<(), Error> {
193 Snapshot1::fd_fdstat_set_rights(
194 self,
195 memory,
196 fd.into(),
197 fs_rights_base.into(),
198 fs_rights_inheriting.into(),
199 )?;
200 Ok(())
201 }
202
203 async fn fd_filestat_get(
204 &mut self,
205 memory: &mut GuestMemory<'_>,
206 fd: types::Fd,
207 ) -> Result<types::Filestat, Error> {
208 Ok(Snapshot1::fd_filestat_get(self, memory, fd.into())
209 .await?
210 .into())
211 }
212
213 async fn fd_filestat_set_size(
214 &mut self,
215 memory: &mut GuestMemory<'_>,
216 fd: types::Fd,
217 size: types::Filesize,
218 ) -> Result<(), Error> {
219 Snapshot1::fd_filestat_set_size(self, memory, fd.into(), size).await?;
220 Ok(())
221 }
222
223 async fn fd_filestat_set_times(
224 &mut self,
225 memory: &mut GuestMemory<'_>,
226 fd: types::Fd,
227 atim: types::Timestamp,
228 mtim: types::Timestamp,
229 fst_flags: types::Fstflags,
230 ) -> Result<(), Error> {
231 Snapshot1::fd_filestat_set_times(self, memory, fd.into(), atim, mtim, fst_flags.into())
232 .await?;
233 Ok(())
234 }
235
236 async fn fd_read(
237 &mut self,
238 memory: &mut GuestMemory<'_>,
239 fd: types::Fd,
240 iovs: types::IovecArray,
241 ) -> Result<types::Size, Error> {
242 assert_iovec_array_same();
243 let result = Snapshot1::fd_read(self, memory, fd.into(), iovs.cast()).await?;
244 Ok(result)
245 }
246
247 async fn fd_pread(
248 &mut self,
249 memory: &mut GuestMemory<'_>,
250 fd: types::Fd,
251 iovs: types::IovecArray,
252 offset: types::Filesize,
253 ) -> Result<types::Size, Error> {
254 assert_iovec_array_same();
255 let result = Snapshot1::fd_pread(self, memory, fd.into(), iovs.cast(), offset).await?;
256 Ok(result)
257 }
258
259 async fn fd_write(
260 &mut self,
261 memory: &mut GuestMemory<'_>,
262 fd: types::Fd,
263 ciovs: types::CiovecArray,
264 ) -> Result<types::Size, Error> {
265 assert_ciovec_array_same();
266 let result = Snapshot1::fd_write(self, memory, fd.into(), ciovs.cast()).await?;
267 Ok(result)
268 }
269
270 async fn fd_pwrite(
271 &mut self,
272 memory: &mut GuestMemory<'_>,
273 fd: types::Fd,
274 ciovs: types::CiovecArray,
275 offset: types::Filesize,
276 ) -> Result<types::Size, Error> {
277 assert_ciovec_array_same();
278 let result = Snapshot1::fd_pwrite(self, memory, fd.into(), ciovs.cast(), offset).await?;
279 Ok(result)
280 }
281
282 fn fd_prestat_get(
283 &mut self,
284 memory: &mut GuestMemory<'_>,
285 fd: types::Fd,
286 ) -> Result<types::Prestat, Error> {
287 Ok(Snapshot1::fd_prestat_get(self, memory, fd.into())?.into())
288 }
289
290 fn fd_prestat_dir_name(
291 &mut self,
292 memory: &mut GuestMemory<'_>,
293 fd: types::Fd,
294 path: GuestPtr<u8>,
295 path_max_len: types::Size,
296 ) -> Result<(), Error> {
297 Snapshot1::fd_prestat_dir_name(self, memory, fd.into(), path, path_max_len)?;
298 Ok(())
299 }
300
301 fn fd_renumber(
302 &mut self,
303 memory: &mut GuestMemory<'_>,
304 from: types::Fd,
305 to: types::Fd,
306 ) -> Result<(), Error> {
307 Snapshot1::fd_renumber(self, memory, from.into(), to.into())?;
308 Ok(())
309 }
310
311 async fn fd_seek(
312 &mut self,
313 memory: &mut GuestMemory<'_>,
314 fd: types::Fd,
315 offset: types::Filedelta,
316 whence: types::Whence,
317 ) -> Result<types::Filesize, Error> {
318 Ok(Snapshot1::fd_seek(self, memory, fd.into(), offset, whence.into()).await?)
319 }
320
321 async fn fd_sync(&mut self, memory: &mut GuestMemory<'_>, fd: types::Fd) -> Result<(), Error> {
322 Snapshot1::fd_sync(self, memory, fd.into()).await?;
323 Ok(())
324 }
325
326 fn fd_tell(
327 &mut self,
328 memory: &mut GuestMemory<'_>,
329 fd: types::Fd,
330 ) -> Result<types::Filesize, Error> {
331 Ok(Snapshot1::fd_tell(self, memory, fd.into())?)
332 }
333
334 async fn fd_readdir(
335 &mut self,
336 memory: &mut GuestMemory<'_>,
337 fd: types::Fd,
338 buf: GuestPtr<u8>,
339 buf_len: types::Size,
340 cookie: types::Dircookie,
341 ) -> Result<types::Size, Error> {
342 Ok(Snapshot1::fd_readdir(self, memory, fd.into(), buf, buf_len, cookie).await?)
343 }
344
345 async fn path_create_directory(
346 &mut self,
347 memory: &mut GuestMemory<'_>,
348 dirfd: types::Fd,
349 path: GuestPtr<str>,
350 ) -> Result<(), Error> {
351 Snapshot1::path_create_directory(self, memory, dirfd.into(), path).await?;
352 Ok(())
353 }
354
355 async fn path_filestat_get(
356 &mut self,
357 memory: &mut GuestMemory<'_>,
358 dirfd: types::Fd,
359 flags: types::Lookupflags,
360 path: GuestPtr<str>,
361 ) -> Result<types::Filestat, Error> {
362 Ok(
363 Snapshot1::path_filestat_get(self, memory, dirfd.into(), flags.into(), path)
364 .await?
365 .into(),
366 )
367 }
368
369 async fn path_filestat_set_times(
370 &mut self,
371 memory: &mut GuestMemory<'_>,
372 dirfd: types::Fd,
373 flags: types::Lookupflags,
374 path: GuestPtr<str>,
375 atim: types::Timestamp,
376 mtim: types::Timestamp,
377 fst_flags: types::Fstflags,
378 ) -> Result<(), Error> {
379 Snapshot1::path_filestat_set_times(
380 self,
381 memory,
382 dirfd.into(),
383 flags.into(),
384 path,
385 atim,
386 mtim,
387 fst_flags.into(),
388 )
389 .await?;
390 Ok(())
391 }
392
393 async fn path_link(
394 &mut self,
395 memory: &mut GuestMemory<'_>,
396 src_fd: types::Fd,
397 src_flags: types::Lookupflags,
398 src_path: GuestPtr<str>,
399 target_fd: types::Fd,
400 target_path: GuestPtr<str>,
401 ) -> Result<(), Error> {
402 Snapshot1::path_link(
403 self,
404 memory,
405 src_fd.into(),
406 src_flags.into(),
407 src_path,
408 target_fd.into(),
409 target_path,
410 )
411 .await?;
412 Ok(())
413 }
414
415 async fn path_open(
416 &mut self,
417 memory: &mut GuestMemory<'_>,
418 dirfd: types::Fd,
419 dirflags: types::Lookupflags,
420 path: GuestPtr<str>,
421 oflags: types::Oflags,
422 fs_rights_base: types::Rights,
423 fs_rights_inheriting: types::Rights,
424 fdflags: types::Fdflags,
425 ) -> Result<types::Fd, Error> {
426 Ok(Snapshot1::path_open(
427 self,
428 memory,
429 dirfd.into(),
430 dirflags.into(),
431 path,
432 oflags.into(),
433 fs_rights_base.into(),
434 fs_rights_inheriting.into(),
435 fdflags.into(),
436 )
437 .await?
438 .into())
439 }
440
441 async fn path_readlink(
442 &mut self,
443 memory: &mut GuestMemory<'_>,
444 dirfd: types::Fd,
445 path: GuestPtr<str>,
446 buf: GuestPtr<u8>,
447 buf_len: types::Size,
448 ) -> Result<types::Size, Error> {
449 Ok(Snapshot1::path_readlink(self, memory, dirfd.into(), path, buf, buf_len).await?)
450 }
451
452 async fn path_remove_directory(
453 &mut self,
454 memory: &mut GuestMemory<'_>,
455 dirfd: types::Fd,
456 path: GuestPtr<str>,
457 ) -> Result<(), Error> {
458 Snapshot1::path_remove_directory(self, memory, dirfd.into(), path).await?;
459 Ok(())
460 }
461
462 async fn path_rename(
463 &mut self,
464 memory: &mut GuestMemory<'_>,
465 src_fd: types::Fd,
466 src_path: GuestPtr<str>,
467 dest_fd: types::Fd,
468 dest_path: GuestPtr<str>,
469 ) -> Result<(), Error> {
470 Snapshot1::path_rename(
471 self,
472 memory,
473 src_fd.into(),
474 src_path,
475 dest_fd.into(),
476 dest_path,
477 )
478 .await?;
479 Ok(())
480 }
481
482 async fn path_symlink(
483 &mut self,
484 memory: &mut GuestMemory<'_>,
485 src_path: GuestPtr<str>,
486 dirfd: types::Fd,
487 dest_path: GuestPtr<str>,
488 ) -> Result<(), Error> {
489 Snapshot1::path_symlink(self, memory, src_path, dirfd.into(), dest_path).await?;
490 Ok(())
491 }
492
493 async fn path_unlink_file(
494 &mut self,
495 memory: &mut GuestMemory<'_>,
496 dirfd: types::Fd,
497 path: GuestPtr<str>,
498 ) -> Result<(), Error> {
499 Snapshot1::path_unlink_file(self, memory, dirfd.into(), path).await?;
500 Ok(())
501 }
502
503 async fn poll_oneoff(
512 &mut self,
513 memory: &mut GuestMemory<'_>,
514 subs: GuestPtr<types::Subscription>,
515 events: GuestPtr<types::Event>,
516 nsubscriptions: types::Size,
517 ) -> Result<types::Size, Error> {
518 let subs_array = subs.as_array(nsubscriptions);
519 let mut old_subs = Vec::new();
520 for slot in subs_array.iter() {
521 let slot = slot?;
522 let sub = memory.read(slot)?;
523 old_subs.push(sub.clone());
524 memory.write(
525 slot.cast(),
526 snapshot1_types::Subscription {
527 userdata: sub.userdata,
528 u: match sub.u {
529 types::SubscriptionU::Clock(c) => {
530 snapshot1_types::SubscriptionU::Clock(c.into())
531 }
532 types::SubscriptionU::FdRead(c) => {
533 snapshot1_types::SubscriptionU::FdRead(c.into())
534 }
535 types::SubscriptionU::FdWrite(c) => {
536 snapshot1_types::SubscriptionU::FdWrite(c.into())
537 }
538 },
539 },
540 )?;
541 }
542 let ret = Snapshot1::poll_oneoff(self, memory, subs.cast(), events.cast(), nsubscriptions)
543 .await?;
544 for (sub, slot) in old_subs.into_iter().zip(subs_array.iter()) {
545 memory.write(slot?, sub)?;
546 }
547 Ok(ret)
548 }
549
550 fn proc_exit(
551 &mut self,
552 memory: &mut GuestMemory<'_>,
553 status: types::Exitcode,
554 ) -> anyhow::Error {
555 Snapshot1::proc_exit(self, memory, status)
556 }
557
558 fn proc_raise(
559 &mut self,
560 memory: &mut GuestMemory<'_>,
561 sig: types::Signal,
562 ) -> Result<(), Error> {
563 Snapshot1::proc_raise(self, memory, sig.into())?;
564 Ok(())
565 }
566
567 fn sched_yield(&mut self, memory: &mut GuestMemory<'_>) -> Result<(), Error> {
568 Snapshot1::sched_yield(self, memory)?;
569 Ok(())
570 }
571
572 fn random_get(
573 &mut self,
574 memory: &mut GuestMemory<'_>,
575 buf: GuestPtr<u8>,
576 buf_len: types::Size,
577 ) -> Result<(), Error> {
578 Snapshot1::random_get(self, memory, buf, buf_len)?;
579 Ok(())
580 }
581
582 fn sock_recv(
583 &mut self,
584 _memory: &mut GuestMemory<'_>,
585 _fd: types::Fd,
586 _ri_data: types::IovecArray,
587 _ri_flags: types::Riflags,
588 ) -> Result<(types::Size, types::Roflags), Error> {
589 Err(Error::trap(anyhow::Error::msg("sock_recv unsupported")))
590 }
591
592 fn sock_send(
593 &mut self,
594 _memory: &mut GuestMemory<'_>,
595 _fd: types::Fd,
596 _si_data: types::CiovecArray,
597 _si_flags: types::Siflags,
598 ) -> Result<types::Size, Error> {
599 Err(Error::trap(anyhow::Error::msg("sock_send unsupported")))
600 }
601
602 fn sock_shutdown(
603 &mut self,
604 _memory: &mut GuestMemory<'_>,
605 _fd: types::Fd,
606 _how: types::Sdflags,
607 ) -> Result<(), Error> {
608 Err(Error::trap(anyhow::Error::msg("sock_shutdown unsupported")))
609 }
610}
611
612fn assert_iovec_array_same() {
613 assert_eq!(
618 std::mem::size_of::<types::IovecArray>(),
619 std::mem::size_of::<snapshot1_types::IovecArray>()
620 );
621}
622
623fn assert_ciovec_array_same() {
624 assert_eq!(
626 std::mem::size_of::<types::CiovecArray>(),
627 std::mem::size_of::<snapshot1_types::CiovecArray>()
628 );
629}
630
631impl From<snapshot1_types::Error> for Error {
632 fn from(error: snapshot1_types::Error) -> Error {
633 match error.downcast() {
634 Ok(errno) => Error::from(types::Errno::from(errno)),
635 Err(trap) => Error::trap(trap),
636 }
637 }
638}
639
640impl From<types::Fd> for snapshot1_types::Fd {
642 fn from(fd: types::Fd) -> snapshot1_types::Fd {
643 u32::from(fd).into()
644 }
645}
646
647impl From<snapshot1_types::Fd> for types::Fd {
649 fn from(fd: snapshot1_types::Fd) -> types::Fd {
650 u32::from(fd).into()
651 }
652}
653
654macro_rules! convert_enum {
660 ($from:ty, $to:ty, $($var:ident),+) => {
661 impl From<$from> for $to {
662 fn from(e: $from) -> $to {
663 match e {
664 $( <$from>::$var => <$to>::$var, )+
665 }
666 }
667 }
668 }
669}
670convert_enum!(
671 snapshot1_types::Errno,
672 types::Errno,
673 Success,
674 TooBig,
675 Acces,
676 Addrinuse,
677 Addrnotavail,
678 Afnosupport,
679 Again,
680 Already,
681 Badf,
682 Badmsg,
683 Busy,
684 Canceled,
685 Child,
686 Connaborted,
687 Connrefused,
688 Connreset,
689 Deadlk,
690 Destaddrreq,
691 Dom,
692 Dquot,
693 Exist,
694 Fault,
695 Fbig,
696 Hostunreach,
697 Idrm,
698 Ilseq,
699 Inprogress,
700 Intr,
701 Inval,
702 Io,
703 Isconn,
704 Isdir,
705 Loop,
706 Mfile,
707 Mlink,
708 Msgsize,
709 Multihop,
710 Nametoolong,
711 Netdown,
712 Netreset,
713 Netunreach,
714 Nfile,
715 Nobufs,
716 Nodev,
717 Noent,
718 Noexec,
719 Nolck,
720 Nolink,
721 Nomem,
722 Nomsg,
723 Noprotoopt,
724 Nospc,
725 Nosys,
726 Notconn,
727 Notdir,
728 Notempty,
729 Notrecoverable,
730 Notsock,
731 Notsup,
732 Notty,
733 Nxio,
734 Overflow,
735 Ownerdead,
736 Perm,
737 Pipe,
738 Proto,
739 Protonosupport,
740 Prototype,
741 Range,
742 Rofs,
743 Spipe,
744 Srch,
745 Stale,
746 Timedout,
747 Txtbsy,
748 Xdev,
749 Notcapable
750);
751convert_enum!(
752 types::Clockid,
753 snapshot1_types::Clockid,
754 Realtime,
755 Monotonic,
756 ProcessCputimeId,
757 ThreadCputimeId
758);
759
760convert_enum!(
761 types::Advice,
762 snapshot1_types::Advice,
763 Normal,
764 Sequential,
765 Random,
766 Willneed,
767 Dontneed,
768 Noreuse
769);
770convert_enum!(
771 snapshot1_types::Filetype,
772 types::Filetype,
773 Directory,
774 BlockDevice,
775 CharacterDevice,
776 RegularFile,
777 SocketDgram,
778 SocketStream,
779 SymbolicLink,
780 Unknown
781);
782convert_enum!(types::Whence, snapshot1_types::Whence, Cur, End, Set);
783
784convert_enum!(
785 types::Signal,
786 snapshot1_types::Signal,
787 None,
788 Hup,
789 Int,
790 Quit,
791 Ill,
792 Trap,
793 Abrt,
794 Bus,
795 Fpe,
796 Kill,
797 Usr1,
798 Segv,
799 Usr2,
800 Pipe,
801 Alrm,
802 Term,
803 Chld,
804 Cont,
805 Stop,
806 Tstp,
807 Ttin,
808 Ttou,
809 Urg,
810 Xcpu,
811 Xfsz,
812 Vtalrm,
813 Prof,
814 Winch,
815 Poll,
816 Pwr,
817 Sys
818);
819
820impl From<snapshot1_types::Prestat> for types::Prestat {
823 fn from(p: snapshot1_types::Prestat) -> types::Prestat {
824 match p {
825 snapshot1_types::Prestat::Dir(d) => types::Prestat::Dir(d.into()),
826 }
827 }
828}
829
830macro_rules! convert_struct {
833 ($from:ty, $to:path, $($field:ident),+) => {
834 impl From<$from> for $to {
835 fn from(e: $from) -> $to {
836 $to {
837 $( $field: e.$field.into(), )+
838 }
839 }
840 }
841 }
842}
843
844convert_struct!(snapshot1_types::PrestatDir, types::PrestatDir, pr_name_len);
845convert_struct!(
846 snapshot1_types::Fdstat,
847 types::Fdstat,
848 fs_filetype,
849 fs_rights_base,
850 fs_rights_inheriting,
851 fs_flags
852);
853convert_struct!(
854 types::SubscriptionClock,
855 snapshot1_types::SubscriptionClock,
856 id,
857 timeout,
858 precision,
859 flags
860);
861convert_struct!(
862 types::SubscriptionFdReadwrite,
863 snapshot1_types::SubscriptionFdReadwrite,
864 file_descriptor
865);
866
867impl From<snapshot1_types::Filestat> for types::Filestat {
871 fn from(f: snapshot1_types::Filestat) -> types::Filestat {
872 types::Filestat {
873 dev: f.dev.into(),
874 ino: f.ino.into(),
875 filetype: f.filetype.into(),
876 nlink: f.nlink.try_into().unwrap_or(u32::MAX),
877 size: f.size.into(),
878 atim: f.atim.into(),
879 mtim: f.mtim.into(),
880 ctim: f.ctim.into(),
881 }
882 }
883}
884
885macro_rules! convert_flags {
887 ($from:ty, $to:ty, $($flag:ident),+) => {
888 impl From<$from> for $to {
889 fn from(f: $from) -> $to {
890 let mut out = <$to>::empty();
891 $(
892 if f.contains(<$from>::$flag) {
893 out |= <$to>::$flag;
894 }
895 )+
896 out
897 }
898 }
899 }
900}
901
902macro_rules! convert_flags_bidirectional {
904 ($from:ty, $to:ty, $($flag:tt)*) => {
905 convert_flags!($from, $to, $($flag)*);
906 convert_flags!($to, $from, $($flag)*);
907 }
908}
909
910convert_flags_bidirectional!(
911 snapshot1_types::Fdflags,
912 types::Fdflags,
913 APPEND,
914 DSYNC,
915 NONBLOCK,
916 RSYNC,
917 SYNC
918);
919convert_flags!(
920 types::Lookupflags,
921 snapshot1_types::Lookupflags,
922 SYMLINK_FOLLOW
923);
924convert_flags!(
925 types::Fstflags,
926 snapshot1_types::Fstflags,
927 ATIM,
928 ATIM_NOW,
929 MTIM,
930 MTIM_NOW
931);
932convert_flags!(
933 types::Oflags,
934 snapshot1_types::Oflags,
935 CREAT,
936 DIRECTORY,
937 EXCL,
938 TRUNC
939);
940convert_flags_bidirectional!(
941 types::Rights,
942 snapshot1_types::Rights,
943 FD_DATASYNC,
944 FD_READ,
945 FD_SEEK,
946 FD_FDSTAT_SET_FLAGS,
947 FD_SYNC,
948 FD_TELL,
949 FD_WRITE,
950 FD_ADVISE,
951 FD_ALLOCATE,
952 PATH_CREATE_DIRECTORY,
953 PATH_CREATE_FILE,
954 PATH_LINK_SOURCE,
955 PATH_LINK_TARGET,
956 PATH_OPEN,
957 FD_READDIR,
958 PATH_READLINK,
959 PATH_RENAME_SOURCE,
960 PATH_RENAME_TARGET,
961 PATH_FILESTAT_GET,
962 PATH_FILESTAT_SET_SIZE,
963 PATH_FILESTAT_SET_TIMES,
964 FD_FILESTAT_GET,
965 FD_FILESTAT_SET_SIZE,
966 FD_FILESTAT_SET_TIMES,
967 PATH_SYMLINK,
968 PATH_REMOVE_DIRECTORY,
969 PATH_UNLINK_FILE,
970 POLL_FD_READWRITE,
971 SOCK_SHUTDOWN
972);
973convert_flags!(
974 types::Subclockflags,
975 snapshot1_types::Subclockflags,
976 SUBSCRIPTION_CLOCK_ABSTIME
977);
978
979impl From<GuestError> for types::Error {
980 fn from(err: GuestError) -> Self {
981 snapshot1_types::Error::from(err).into()
982 }
983}