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) -> wasmtime::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) -> wasmtime::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 std::future::Future;
42 use wasmtime::Result;
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 ) -> wasmtime::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(wasmtime::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(wasmtime::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(wasmtime::Error::msg(
608 "sock_shutdown unsupported",
609 )))
610 }
611}
612
613fn assert_iovec_array_same() {
614 assert_eq!(
619 std::mem::size_of::<types::IovecArray>(),
620 std::mem::size_of::<snapshot1_types::IovecArray>()
621 );
622}
623
624fn assert_ciovec_array_same() {
625 assert_eq!(
627 std::mem::size_of::<types::CiovecArray>(),
628 std::mem::size_of::<snapshot1_types::CiovecArray>()
629 );
630}
631
632impl From<snapshot1_types::Error> for Error {
633 fn from(error: snapshot1_types::Error) -> Error {
634 match error.downcast() {
635 Ok(errno) => Error::from(types::Errno::from(errno)),
636 Err(trap) => Error::trap(trap),
637 }
638 }
639}
640
641impl From<types::Fd> for snapshot1_types::Fd {
643 fn from(fd: types::Fd) -> snapshot1_types::Fd {
644 u32::from(fd).into()
645 }
646}
647
648impl From<snapshot1_types::Fd> for types::Fd {
650 fn from(fd: snapshot1_types::Fd) -> types::Fd {
651 u32::from(fd).into()
652 }
653}
654
655macro_rules! convert_enum {
661 ($from:ty, $to:ty, $($var:ident),+) => {
662 impl From<$from> for $to {
663 fn from(e: $from) -> $to {
664 match e {
665 $( <$from>::$var => <$to>::$var, )+
666 }
667 }
668 }
669 }
670}
671convert_enum!(
672 snapshot1_types::Errno,
673 types::Errno,
674 Success,
675 TooBig,
676 Acces,
677 Addrinuse,
678 Addrnotavail,
679 Afnosupport,
680 Again,
681 Already,
682 Badf,
683 Badmsg,
684 Busy,
685 Canceled,
686 Child,
687 Connaborted,
688 Connrefused,
689 Connreset,
690 Deadlk,
691 Destaddrreq,
692 Dom,
693 Dquot,
694 Exist,
695 Fault,
696 Fbig,
697 Hostunreach,
698 Idrm,
699 Ilseq,
700 Inprogress,
701 Intr,
702 Inval,
703 Io,
704 Isconn,
705 Isdir,
706 Loop,
707 Mfile,
708 Mlink,
709 Msgsize,
710 Multihop,
711 Nametoolong,
712 Netdown,
713 Netreset,
714 Netunreach,
715 Nfile,
716 Nobufs,
717 Nodev,
718 Noent,
719 Noexec,
720 Nolck,
721 Nolink,
722 Nomem,
723 Nomsg,
724 Noprotoopt,
725 Nospc,
726 Nosys,
727 Notconn,
728 Notdir,
729 Notempty,
730 Notrecoverable,
731 Notsock,
732 Notsup,
733 Notty,
734 Nxio,
735 Overflow,
736 Ownerdead,
737 Perm,
738 Pipe,
739 Proto,
740 Protonosupport,
741 Prototype,
742 Range,
743 Rofs,
744 Spipe,
745 Srch,
746 Stale,
747 Timedout,
748 Txtbsy,
749 Xdev,
750 Notcapable
751);
752convert_enum!(
753 types::Clockid,
754 snapshot1_types::Clockid,
755 Realtime,
756 Monotonic,
757 ProcessCputimeId,
758 ThreadCputimeId
759);
760
761convert_enum!(
762 types::Advice,
763 snapshot1_types::Advice,
764 Normal,
765 Sequential,
766 Random,
767 Willneed,
768 Dontneed,
769 Noreuse
770);
771convert_enum!(
772 snapshot1_types::Filetype,
773 types::Filetype,
774 Directory,
775 BlockDevice,
776 CharacterDevice,
777 RegularFile,
778 SocketDgram,
779 SocketStream,
780 SymbolicLink,
781 Unknown
782);
783convert_enum!(types::Whence, snapshot1_types::Whence, Cur, End, Set);
784
785convert_enum!(
786 types::Signal,
787 snapshot1_types::Signal,
788 None,
789 Hup,
790 Int,
791 Quit,
792 Ill,
793 Trap,
794 Abrt,
795 Bus,
796 Fpe,
797 Kill,
798 Usr1,
799 Segv,
800 Usr2,
801 Pipe,
802 Alrm,
803 Term,
804 Chld,
805 Cont,
806 Stop,
807 Tstp,
808 Ttin,
809 Ttou,
810 Urg,
811 Xcpu,
812 Xfsz,
813 Vtalrm,
814 Prof,
815 Winch,
816 Poll,
817 Pwr,
818 Sys
819);
820
821impl From<snapshot1_types::Prestat> for types::Prestat {
824 fn from(p: snapshot1_types::Prestat) -> types::Prestat {
825 match p {
826 snapshot1_types::Prestat::Dir(d) => types::Prestat::Dir(d.into()),
827 }
828 }
829}
830
831macro_rules! convert_struct {
834 ($from:ty, $to:path, $($field:ident),+) => {
835 impl From<$from> for $to {
836 fn from(e: $from) -> $to {
837 $to {
838 $( $field: e.$field.into(), )+
839 }
840 }
841 }
842 }
843}
844
845convert_struct!(snapshot1_types::PrestatDir, types::PrestatDir, pr_name_len);
846convert_struct!(
847 snapshot1_types::Fdstat,
848 types::Fdstat,
849 fs_filetype,
850 fs_rights_base,
851 fs_rights_inheriting,
852 fs_flags
853);
854convert_struct!(
855 types::SubscriptionClock,
856 snapshot1_types::SubscriptionClock,
857 id,
858 timeout,
859 precision,
860 flags
861);
862convert_struct!(
863 types::SubscriptionFdReadwrite,
864 snapshot1_types::SubscriptionFdReadwrite,
865 file_descriptor
866);
867
868impl From<snapshot1_types::Filestat> for types::Filestat {
872 fn from(f: snapshot1_types::Filestat) -> types::Filestat {
873 types::Filestat {
874 dev: f.dev,
875 ino: f.ino,
876 filetype: f.filetype.into(),
877 nlink: f.nlink.try_into().unwrap_or(u32::MAX),
878 size: f.size,
879 atim: f.atim,
880 mtim: f.mtim,
881 ctim: f.ctim,
882 }
883 }
884}
885
886macro_rules! convert_flags {
888 ($from:ty, $to:ty, $($flag:ident),+) => {
889 impl From<$from> for $to {
890 fn from(f: $from) -> $to {
891 let mut out = <$to>::empty();
892 $(
893 if f.contains(<$from>::$flag) {
894 out |= <$to>::$flag;
895 }
896 )+
897 out
898 }
899 }
900 }
901}
902
903macro_rules! convert_flags_bidirectional {
905 ($from:ty, $to:ty, $($flag:tt)*) => {
906 convert_flags!($from, $to, $($flag)*);
907 convert_flags!($to, $from, $($flag)*);
908 }
909}
910
911convert_flags_bidirectional!(
912 snapshot1_types::Fdflags,
913 types::Fdflags,
914 APPEND,
915 DSYNC,
916 NONBLOCK,
917 RSYNC,
918 SYNC
919);
920convert_flags!(
921 types::Lookupflags,
922 snapshot1_types::Lookupflags,
923 SYMLINK_FOLLOW
924);
925convert_flags!(
926 types::Fstflags,
927 snapshot1_types::Fstflags,
928 ATIM,
929 ATIM_NOW,
930 MTIM,
931 MTIM_NOW
932);
933convert_flags!(
934 types::Oflags,
935 snapshot1_types::Oflags,
936 CREAT,
937 DIRECTORY,
938 EXCL,
939 TRUNC
940);
941convert_flags_bidirectional!(
942 types::Rights,
943 snapshot1_types::Rights,
944 FD_DATASYNC,
945 FD_READ,
946 FD_SEEK,
947 FD_FDSTAT_SET_FLAGS,
948 FD_SYNC,
949 FD_TELL,
950 FD_WRITE,
951 FD_ADVISE,
952 FD_ALLOCATE,
953 PATH_CREATE_DIRECTORY,
954 PATH_CREATE_FILE,
955 PATH_LINK_SOURCE,
956 PATH_LINK_TARGET,
957 PATH_OPEN,
958 FD_READDIR,
959 PATH_READLINK,
960 PATH_RENAME_SOURCE,
961 PATH_RENAME_TARGET,
962 PATH_FILESTAT_GET,
963 PATH_FILESTAT_SET_SIZE,
964 PATH_FILESTAT_SET_TIMES,
965 FD_FILESTAT_GET,
966 FD_FILESTAT_SET_SIZE,
967 FD_FILESTAT_SET_TIMES,
968 PATH_SYMLINK,
969 PATH_REMOVE_DIRECTORY,
970 PATH_UNLINK_FILE,
971 POLL_FD_READWRITE,
972 SOCK_SHUTDOWN
973);
974convert_flags!(
975 types::Subclockflags,
976 snapshot1_types::Subclockflags,
977 SUBSCRIPTION_CLOCK_ABSTIME
978);
979
980impl From<GuestError> for types::Error {
981 fn from(err: GuestError) -> Self {
982 snapshot1_types::Error::from(err).into()
983 }
984}