maybe_fut/api/io/
stdin.rs1#[derive(Debug, Read, Unwrap)]
3#[io(feature("tokio"))]
4#[unwrap_types(std(std::io::Stdin), tokio(tokio::io::Stdin), tokio_gated("tokio"))]
5pub struct Stdin(StdinInner);
6
7#[derive(Debug)]
8enum StdinInner {
9 Std(std::io::Stdin),
10 #[cfg(tokio)]
11 Tokio(tokio::io::Stdin),
12}
13
14impl From<std::io::Stdin> for Stdin {
15 fn from(stdin: std::io::Stdin) -> Self {
16 Self(StdinInner::Std(stdin))
17 }
18}
19
20#[cfg(tokio)]
21#[cfg_attr(docsrs, doc(cfg(feature = "tokio")))]
22impl From<tokio::io::Stdin> for Stdin {
23 fn from(stdin: tokio::io::Stdin) -> Self {
24 Self(StdinInner::Tokio(stdin))
25 }
26}
27
28pub fn stdin() -> Stdin {
30 #[cfg(tokio)]
31 {
32 if crate::is_async_context() {
33 tokio::io::stdin().into()
34 } else {
35 std::io::stdin().into()
36 }
37 }
38 #[cfg(not(tokio))]
39 {
40 std::io::stdin().into()
41 }
42}
43
44#[cfg(unix)]
45impl std::os::fd::AsFd for Stdin {
46 fn as_fd(&self) -> std::os::fd::BorrowedFd<'_> {
47 match &self.0 {
48 StdinInner::Std(file) => file.as_fd(),
49 #[cfg(tokio)]
50 StdinInner::Tokio(file) => file.as_fd(),
51 }
52 }
53}
54
55#[cfg(windows)]
56impl std::os::windows::io::AsHandle for Stdin {
57 fn as_handle(&self) -> std::os::windows::io::BorrowedHandle<'_> {
58 match &self.0 {
59 StdinInner::Std(file) => file.as_handle(),
60 #[cfg(tokio)]
61 StdinInner::Tokio(file) => file.as_handle(),
62 }
63 }
64}
65
66#[cfg(unix)]
67impl std::os::fd::AsRawFd for Stdin {
68 fn as_raw_fd(&self) -> std::os::fd::RawFd {
69 match &self.0 {
70 StdinInner::Std(file) => file.as_raw_fd(),
71 #[cfg(tokio)]
72 StdinInner::Tokio(file) => file.as_raw_fd(),
73 }
74 }
75}
76
77#[cfg(windows)]
78impl std::os::windows::io::AsRawHandle for Stdin {
79 fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
80 match &self.0 {
81 StdinInner::Std(file) => file.as_raw_handle(),
82 #[cfg(tokio)]
83 StdinInner::Tokio(file) => file.as_raw_handle(),
84 }
85 }
86}
87
88#[cfg(test)]
89mod test {
90
91 use super::*;
92
93 #[test]
94 fn test_should_stdin_sync() {
95 let stdin = stdin();
96 assert!(matches!(stdin.0, StdinInner::Std(_)));
97 }
98
99 #[cfg(tokio)]
100 #[tokio::test]
101 async fn test_should_stdin_async() {
102 let stdin = stdin();
103 assert!(matches!(stdin.0, StdinInner::Tokio(_)));
104 }
105}