async_ssh2_lite/session_stream/
mod.rs1use core::{
2 task::{Context, Poll},
3 time::Duration,
4};
5use std::io::Error as IoError;
6
7use async_trait::async_trait;
8use ssh2::{BlockDirections, Error as Ssh2Error, Session};
9
10use crate::error::Error;
11
12#[cfg(feature = "async-io")]
14mod impl_async_io;
15#[cfg(feature = "tokio")]
16mod impl_tokio;
17
18#[async_trait]
20pub trait AsyncSessionStream {
21 async fn x_with<R>(
23 &self,
24 op: impl FnMut() -> Result<R, Ssh2Error> + Send,
25 sess: &Session,
26 expected_block_directions: BlockDirections,
27 sleep_dur: Option<Duration>,
28 ) -> Result<R, Error>;
29
30 async fn rw_with<R>(
31 &self,
32 op: impl FnMut() -> Result<R, Ssh2Error> + Send,
33 sess: &Session,
34 ) -> Result<R, Error> {
35 self.x_with(
36 op,
37 sess,
38 BlockDirections::Both,
39 Some(Duration::from_millis(1)),
40 )
41 .await
42 }
43
44 async fn none_with<R>(
45 &self,
46 op: impl FnMut() -> Result<R, Ssh2Error> + Send,
47 sess: &Session,
48 ) -> Result<R, Error> {
49 self.x_with(
50 op,
51 sess,
52 BlockDirections::None,
53 Some(Duration::from_millis(1)),
54 )
55 .await
56 }
57
58 async fn read_with<R>(
59 &self,
60 op: impl FnMut() -> Result<R, Ssh2Error> + Send,
61 sess: &Session,
62 ) -> Result<R, Error> {
63 self.x_with(
64 op,
65 sess,
66 BlockDirections::Inbound,
67 Some(Duration::from_millis(1)),
68 )
69 .await
70 }
71
72 async fn write_with<R>(
73 &self,
74 op: impl FnMut() -> Result<R, Ssh2Error> + Send,
75 sess: &Session,
76 ) -> Result<R, Error> {
77 self.x_with(
78 op,
79 sess,
80 BlockDirections::Outbound,
81 Some(Duration::from_millis(1)),
82 )
83 .await
84 }
85
86 fn poll_x_with<R>(
88 &self,
89 cx: &mut Context,
90 op: impl FnMut() -> Result<R, IoError> + Send,
91 sess: &Session,
92 expected_block_directions: BlockDirections,
93 sleep_dur: Option<Duration>,
94 ) -> Poll<Result<R, IoError>>;
95
96 fn poll_read_with<R>(
97 &self,
98 cx: &mut Context,
99 op: impl FnMut() -> Result<R, IoError> + Send,
100 sess: &Session,
101 ) -> Poll<Result<R, IoError>> {
102 self.poll_x_with(
103 cx,
104 op,
105 sess,
106 BlockDirections::Inbound,
107 Some(Duration::from_millis(1)),
108 )
109 }
110
111 fn poll_write_with<R>(
112 &self,
113 cx: &mut Context,
114 op: impl FnMut() -> Result<R, IoError> + Send,
115 sess: &Session,
116 ) -> Poll<Result<R, IoError>> {
117 self.poll_x_with(
118 cx,
119 op,
120 sess,
121 BlockDirections::Both,
122 Some(Duration::from_millis(1)),
123 )
124 }
125}
126
127pub trait BlockDirectionsExt {
129 fn is_readable(&self) -> bool;
130 fn is_writable(&self) -> bool;
131}
132impl BlockDirectionsExt for BlockDirections {
133 fn is_readable(&self) -> bool {
134 matches!(self, BlockDirections::Inbound | BlockDirections::Both)
135 }
136
137 fn is_writable(&self) -> bool {
138 matches!(self, BlockDirections::Outbound | BlockDirections::Both)
139 }
140}
141
142#[cfg(test)]
143mod tests {
144 use super::*;
145
146 #[test]
147 fn test_block_directions_ext() {
148 assert!(!BlockDirections::None.is_readable());
149 assert!(!BlockDirections::None.is_writable());
150 assert!(BlockDirections::Inbound.is_readable());
151 assert!(!BlockDirections::Inbound.is_writable());
152 assert!(!BlockDirections::Outbound.is_readable());
153 assert!(BlockDirections::Outbound.is_writable());
154 assert!(BlockDirections::Both.is_readable());
155 assert!(BlockDirections::Both.is_writable());
156 }
157}