Skip to main content

wasmtime_wasi/p2/
stdio.rs

1use crate::cli::{IsTerminal, WasiCliCtxView};
2use crate::p2::bindings::cli::{
3    stderr, stdin, stdout, terminal_input, terminal_output, terminal_stderr, terminal_stdin,
4    terminal_stdout,
5};
6use wasmtime::component::Resource;
7use wasmtime_wasi_io::streams;
8
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10pub enum IsATTY {
11    Yes,
12    No,
13}
14
15impl stdin::Host for WasiCliCtxView<'_> {
16    fn get_stdin(&mut self) -> Result<Resource<streams::DynInputStream>, wasmtime::Error> {
17        let stream = self.ctx.stdin.p2_stream();
18        Ok(self.table.push(stream)?)
19    }
20}
21
22impl stdout::Host for WasiCliCtxView<'_> {
23    fn get_stdout(&mut self) -> Result<Resource<streams::DynOutputStream>, wasmtime::Error> {
24        let stream = self.ctx.stdout.p2_stream();
25        Ok(self.table.push(stream)?)
26    }
27}
28
29impl stderr::Host for WasiCliCtxView<'_> {
30    fn get_stderr(&mut self) -> Result<Resource<streams::DynOutputStream>, wasmtime::Error> {
31        let stream = self.ctx.stderr.p2_stream();
32        Ok(self.table.push(stream)?)
33    }
34}
35
36pub struct TerminalInput;
37pub struct TerminalOutput;
38
39impl terminal_input::Host for WasiCliCtxView<'_> {}
40impl terminal_input::HostTerminalInput for WasiCliCtxView<'_> {
41    fn drop(&mut self, r: Resource<TerminalInput>) -> wasmtime::Result<()> {
42        self.table.delete(r)?;
43        Ok(())
44    }
45}
46impl terminal_output::Host for WasiCliCtxView<'_> {}
47impl terminal_output::HostTerminalOutput for WasiCliCtxView<'_> {
48    fn drop(&mut self, r: Resource<TerminalOutput>) -> wasmtime::Result<()> {
49        self.table.delete(r)?;
50        Ok(())
51    }
52}
53impl terminal_stdin::Host for WasiCliCtxView<'_> {
54    fn get_terminal_stdin(&mut self) -> wasmtime::Result<Option<Resource<TerminalInput>>> {
55        if self.ctx.stdin.is_terminal() {
56            let fd = self.table.push(TerminalInput)?;
57            Ok(Some(fd))
58        } else {
59            Ok(None)
60        }
61    }
62}
63impl terminal_stdout::Host for WasiCliCtxView<'_> {
64    fn get_terminal_stdout(&mut self) -> wasmtime::Result<Option<Resource<TerminalOutput>>> {
65        if self.ctx.stdout.is_terminal() {
66            let fd = self.table.push(TerminalOutput)?;
67            Ok(Some(fd))
68        } else {
69            Ok(None)
70        }
71    }
72}
73impl terminal_stderr::Host for WasiCliCtxView<'_> {
74    fn get_terminal_stderr(&mut self) -> wasmtime::Result<Option<Resource<TerminalOutput>>> {
75        if self.ctx.stderr.is_terminal() {
76            let fd = self.table.push(TerminalOutput)?;
77            Ok(Some(fd))
78        } else {
79            Ok(None)
80        }
81    }
82}
83
84mod named {
85    use crate::cli::WasiCliNamedView;
86    use crate::p2::bindings::named_imports::wasi::cli::{
87        stderr, stdin, stdout, terminal_input, terminal_output, terminal_stderr, terminal_stdin,
88        terminal_stdout,
89    };
90    use crate::p2::stdio::{TerminalInput, TerminalOutput};
91    use crate::{NamedId, WasiCtxNamedView};
92    use wasmtime::component::Resource;
93    use wasmtime_wasi_io::streams;
94
95    impl<T> stdin::Host for WasiCtxNamedView<'_, T>
96    where
97        T: WasiCliNamedView,
98    {
99        fn get_stdin(
100            &mut self,
101            id: NamedId,
102        ) -> Result<Resource<streams::DynInputStream>, wasmtime::Error> {
103            super::stdin::Host::get_stdin(&mut self.0.cli(id))
104        }
105    }
106
107    impl<T> stdout::Host for WasiCtxNamedView<'_, T>
108    where
109        T: WasiCliNamedView,
110    {
111        fn get_stdout(
112            &mut self,
113            id: NamedId,
114        ) -> Result<Resource<streams::DynOutputStream>, wasmtime::Error> {
115            super::stdout::Host::get_stdout(&mut self.0.cli(id))
116        }
117    }
118
119    impl<T> stderr::Host for WasiCtxNamedView<'_, T>
120    where
121        T: WasiCliNamedView,
122    {
123        fn get_stderr(
124            &mut self,
125            id: NamedId,
126        ) -> Result<Resource<streams::DynOutputStream>, wasmtime::Error> {
127            super::stderr::Host::get_stderr(&mut self.0.cli(id))
128        }
129    }
130
131    impl<T> terminal_input::Host for WasiCtxNamedView<'_, T> where T: WasiCliNamedView {}
132    impl<T> terminal_input::HostTerminalInput for WasiCtxNamedView<'_, T>
133    where
134        T: WasiCliNamedView,
135    {
136        fn drop(&mut self, id: NamedId, r: Resource<TerminalInput>) -> wasmtime::Result<()> {
137            super::terminal_input::HostTerminalInput::drop(&mut self.0.cli(id), r)
138        }
139    }
140
141    impl<T> terminal_output::Host for WasiCtxNamedView<'_, T> where T: WasiCliNamedView {}
142    impl<T> terminal_output::HostTerminalOutput for WasiCtxNamedView<'_, T>
143    where
144        T: WasiCliNamedView,
145    {
146        fn drop(&mut self, id: NamedId, r: Resource<TerminalOutput>) -> wasmtime::Result<()> {
147            super::terminal_output::HostTerminalOutput::drop(&mut self.0.cli(id), r)
148        }
149    }
150
151    impl<T> terminal_stdin::Host for WasiCtxNamedView<'_, T>
152    where
153        T: WasiCliNamedView,
154    {
155        fn get_terminal_stdin(
156            &mut self,
157            id: NamedId,
158        ) -> wasmtime::Result<Option<Resource<TerminalInput>>> {
159            super::terminal_stdin::Host::get_terminal_stdin(&mut self.0.cli(id))
160        }
161    }
162
163    impl<T> terminal_stdout::Host for WasiCtxNamedView<'_, T>
164    where
165        T: WasiCliNamedView,
166    {
167        fn get_terminal_stdout(
168            &mut self,
169            id: NamedId,
170        ) -> wasmtime::Result<Option<Resource<TerminalOutput>>> {
171            super::terminal_stdout::Host::get_terminal_stdout(&mut self.0.cli(id))
172        }
173    }
174
175    impl<T> terminal_stderr::Host for WasiCtxNamedView<'_, T>
176    where
177        T: WasiCliNamedView,
178    {
179        fn get_terminal_stderr(
180            &mut self,
181            id: NamedId,
182        ) -> wasmtime::Result<Option<Resource<TerminalOutput>>> {
183            super::terminal_stderr::Host::get_terminal_stderr(&mut self.0.cli(id))
184        }
185    }
186}