1
1
use crate :: error:: ApiError ;
2
2
use crate :: nodes:: { BackgroundNodeClient , NodeManager , NodeManagerWorker } ;
3
3
use miette:: IntoDiagnostic ;
4
- use minicbor:: { CborLen , Decode , Encode } ;
4
+ use minicbor:: encode:: Write ;
5
+ use minicbor:: { encode, CborLen , Decode , Decoder , Encode , Encoder } ;
5
6
use ockam_core:: api:: { Error , Request , Response } ;
6
7
use ockam_core:: { self , async_trait, Decodable , Encodable , Encoded , Message , Result } ;
7
8
use ockam_multiaddr:: MultiAddr ;
@@ -13,23 +14,23 @@ const TARGET: &str = "ockam_api::message";
13
14
14
15
#[ async_trait]
15
16
pub trait Messages {
16
- async fn send_message < R : Message > (
17
+ async fn send_message < T : Message , R : Message > (
17
18
& self ,
18
19
ctx : & Context ,
19
20
to : & MultiAddr ,
20
- message : Vec < u8 > ,
21
+ message : T ,
21
22
timeout : Option < Duration > ,
22
23
) -> miette:: Result < R > ;
23
24
}
24
25
25
26
#[ async_trait]
26
27
impl Messages for NodeManager {
27
28
#[ instrument( skip_all) ]
28
- async fn send_message < R : Message > (
29
+ async fn send_message < T : Message , R : Message > (
29
30
& self ,
30
31
ctx : & Context ,
31
32
to : & MultiAddr ,
32
- message : Vec < u8 > ,
33
+ message : T ,
33
34
timeout : Option < Duration > ,
34
35
) -> miette:: Result < R > {
35
36
let connection = self
@@ -56,11 +57,11 @@ impl Messages for NodeManager {
56
57
#[ async_trait]
57
58
impl Messages for BackgroundNodeClient {
58
59
#[ instrument( skip_all) ]
59
- async fn send_message < R : Message > (
60
+ async fn send_message < T : Message , R : Message > (
60
61
& self ,
61
62
ctx : & Context ,
62
63
to : & MultiAddr ,
63
- message : Vec < u8 > ,
64
+ message : T ,
64
65
timeout : Option < Duration > ,
65
66
) -> miette:: Result < R > {
66
67
let request = Request :: post ( "v0/message" ) . body ( SendMessage :: new ( to, message) ) ;
@@ -69,10 +70,10 @@ impl Messages for BackgroundNodeClient {
69
70
}
70
71
71
72
impl NodeManagerWorker {
72
- pub ( crate ) async fn send_message < R : Message > (
73
+ pub ( crate ) async fn send_message < T : Message , R : Message > (
73
74
& self ,
74
75
ctx : & Context ,
75
- send_message : SendMessage ,
76
+ send_message : SendMessage < T > ,
76
77
) -> Result < Response < R > , Response < Error > > {
77
78
let multiaddr = send_message. multiaddr ( ) ?;
78
79
let msg = send_message. message ;
@@ -96,25 +97,51 @@ impl NodeManagerWorker {
96
97
#[ derive( Debug , Clone , Encode , Decode , CborLen , Message ) ]
97
98
#[ rustfmt:: skip]
98
99
#[ cbor( map) ]
99
- pub struct SendMessage {
100
+ pub struct SendMessage < T : Message > {
100
101
#[ n( 1 ) ] pub route : String ,
101
- #[ n( 2 ) ] pub message : Vec < u8 > ,
102
+ #[ n( 2 ) ] pub message : T ,
102
103
}
103
104
104
- impl Encodable for SendMessage {
105
+ impl < T : Message > SendMessage < T > {
106
+ fn encode_send_message < W > ( self , buf : W ) -> Result < ( ) , encode:: Error < W :: Error > >
107
+ where
108
+ W : Write ,
109
+ {
110
+ let mut e = Encoder :: new ( buf) ;
111
+ e. encode ( & self . route ) ?;
112
+ e. writer_mut ( )
113
+ . write_all ( & <T as Encodable >:: encode ( self . message ) . map_err ( encode:: Error :: message) ?)
114
+ . map_err ( |_| encode:: Error :: message ( "encoding error" ) ) ?;
115
+ Ok ( ( ) )
116
+ }
117
+
118
+ fn into_vec ( self ) -> Result < Vec < u8 > , encode:: Error < <Vec < u8 > as Write >:: Error > > {
119
+ let mut buf = Vec :: new ( ) ;
120
+ self . encode_send_message ( & mut buf) ?;
121
+ Ok ( buf)
122
+ }
123
+ }
124
+
125
+ impl < T : Message > Encodable for SendMessage < T > {
105
126
fn encode ( self ) -> Result < Encoded > {
106
- Ok ( minicbor :: to_vec ( self ) ?)
127
+ Ok ( self . into_vec ( ) ?)
107
128
}
108
129
}
109
130
110
- impl Decodable for SendMessage {
131
+ impl < T : Message > Decodable for SendMessage < T > {
111
132
fn decode ( e : & [ u8 ] ) -> Result < Self > {
112
- Ok ( minicbor:: decode ( e) ?)
133
+ let mut dec = Decoder :: new ( e) ;
134
+ let route: String = dec. decode ( ) ?;
135
+ let message = dec. input ( ) . get ( dec. position ( ) ..e. len ( ) ) . unwrap ( ) ;
136
+ Ok ( SendMessage {
137
+ route,
138
+ message : <T as Decodable >:: decode ( message) ?,
139
+ } )
113
140
}
114
141
}
115
142
116
- impl SendMessage {
117
- pub fn new ( route : & MultiAddr , message : Vec < u8 > ) -> Self {
143
+ impl < T : Message > SendMessage < T > {
144
+ pub fn new ( route : & MultiAddr , message : T ) -> Self {
118
145
Self {
119
146
route : route. to_string ( ) ,
120
147
message,
0 commit comments