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