@@ -7,7 +7,7 @@ use std::{borrow::Cow, fmt::Debug, io};
7
7
8
8
use async_trait:: async_trait;
9
9
10
- use crate :: { frame:: * , slave:: * , Error , Result } ;
10
+ use crate :: { frame:: * , slave:: * , Result } ;
11
11
12
12
#[ cfg( feature = "rtu" ) ]
13
13
pub mod rtu;
@@ -21,11 +21,22 @@ pub mod sync;
21
21
/// Transport independent asynchronous client trait
22
22
#[ async_trait]
23
23
pub trait Client : SlaveContext + Send + Debug {
24
- /// Invoke a _Modbus_ function
24
+ /// Invokes a _Modbus_ function.
25
25
async fn call ( & mut self , request : Request < ' _ > ) -> Result < Response > ;
26
+
27
+ /// Disconnects the client.
28
+ ///
29
+ /// Permanently disconnects the client by shutting down the
30
+ /// underlying stream in a graceful manner (`AsyncDrop`).
31
+ ///
32
+ /// Dropping the client without explicitly disconnecting it
33
+ /// beforehand should also work and free all resources. The
34
+ /// actual behavior might depend on the underlying transport
35
+ /// protocol (RTU/TCP) that is used by the client.
36
+ async fn disconnect ( & mut self ) -> io:: Result < ( ) > ;
26
37
}
27
38
28
- /// Asynchronous Modbus reader
39
+ /// Asynchronous _Modbus_ reader
29
40
#[ async_trait]
30
41
pub trait Reader : Client {
31
42
/// Read multiple coils (0x01)
@@ -83,22 +94,6 @@ pub struct Context {
83
94
client : Box < dyn Client > ,
84
95
}
85
96
86
- impl Context {
87
- /// Disconnect the client
88
- pub async fn disconnect ( & mut self ) -> Result < ( ) > {
89
- // Disconnecting is expected to fail!
90
- let res = self . client . call ( Request :: Disconnect ) . await ;
91
- match res {
92
- Ok ( _) => unreachable ! ( ) ,
93
- Err ( Error :: Transport ( err) ) => match err. kind ( ) {
94
- io:: ErrorKind :: NotConnected | io:: ErrorKind :: BrokenPipe => Ok ( Ok ( ( ) ) ) ,
95
- _ => Err ( Error :: Transport ( err) ) ,
96
- } ,
97
- Err ( err) => Err ( err) ,
98
- }
99
- }
100
- }
101
-
102
97
impl From < Box < dyn Client > > for Context {
103
98
fn from ( client : Box < dyn Client > ) -> Self {
104
99
Self { client }
@@ -116,6 +111,10 @@ impl Client for Context {
116
111
async fn call ( & mut self , request : Request < ' _ > ) -> Result < Response > {
117
112
self . client . call ( request) . await
118
113
}
114
+
115
+ async fn disconnect ( & mut self ) -> io:: Result < ( ) > {
116
+ self . client . disconnect ( ) . await
117
+ }
119
118
}
120
119
121
120
impl SlaveContext for Context {
@@ -319,10 +318,10 @@ impl Writer for Context {
319
318
320
319
#[ cfg( test) ]
321
320
mod tests {
322
- use crate :: Result ;
321
+ use crate :: { Error , Result } ;
323
322
324
323
use super :: * ;
325
- use std:: sync:: Mutex ;
324
+ use std:: { io , sync:: Mutex } ;
326
325
327
326
#[ derive( Default , Debug ) ]
328
327
pub ( crate ) struct ClientMock {
@@ -358,6 +357,10 @@ mod tests {
358
357
Err ( err) => Err ( err) ,
359
358
}
360
359
}
360
+
361
+ async fn disconnect ( & mut self ) -> io:: Result < ( ) > {
362
+ Ok ( ( ) )
363
+ }
361
364
}
362
365
363
366
impl SlaveContext for ClientMock {
0 commit comments