@@ -5,6 +5,7 @@ use std::future::Future;
5
5
use std:: time:: Duration ;
6
6
7
7
use const_format:: formatcp;
8
+ use either:: { Either , Left , Right } ;
8
9
use thiserror:: Error ;
9
10
use tokio:: sync:: { mpsc, watch} ;
10
11
@@ -279,15 +280,25 @@ impl Client {
279
280
receiver
280
281
}
281
282
282
- async fn wait < T , F > ( result : Result < F > ) -> Result < T >
283
+ async fn wait < T , E , F > ( result : std :: result :: Result < F , E > ) -> std :: result :: Result < T , E >
283
284
where
284
- F : Future < Output = Result < T > > , {
285
+ F : Future < Output = std :: result :: Result < T , E > > , {
285
286
match result {
286
287
Err ( err) => Err ( err) ,
287
288
Ok ( future) => future. await ,
288
289
}
289
290
}
290
291
292
+ async fn resolve < T , E , F > ( result : std:: result:: Result < Either < F , T > , E > ) -> std:: result:: Result < T , E >
293
+ where
294
+ F : Future < Output = std:: result:: Result < T , E > > , {
295
+ match result {
296
+ Err ( err) => Err ( err) ,
297
+ Ok ( Right ( r) ) => Ok ( r) ,
298
+ Ok ( Left ( future) ) => future. await ,
299
+ }
300
+ }
301
+
291
302
async fn map_wait < T , U , Fu , Fn > ( result : Result < Fu > , f : Fn ) -> Result < U >
292
303
where
293
304
Fu : Future < Output = Result < T > > ,
@@ -936,8 +947,11 @@ trait MultiBuffer {
936
947
fn op_code ( ) -> OpCode ;
937
948
938
949
fn build_request ( & mut self ) -> MarshalledRequest {
939
- let header = MultiHeader { op : OpCode :: Error , done : true , err : -1 } ;
940
950
let buffer = self . buffer ( ) ;
951
+ if buffer. is_empty ( ) {
952
+ return Default :: default ( ) ;
953
+ }
954
+ let header = MultiHeader { op : OpCode :: Error , done : true , err : -1 } ;
941
955
buffer. append_record ( & header) ;
942
956
buffer. finish ( ) ;
943
957
MarshalledRequest ( std:: mem:: take ( buffer) )
@@ -1014,23 +1028,32 @@ impl<'a> MultiReader<'a> {
1014
1028
///
1015
1029
/// # Notable behaviors
1016
1030
/// Individual errors(eg. [Error::NoNode]) are reported individually through [MultiReadResult::Error].
1017
- pub async fn commit ( & mut self ) -> Result < Vec < MultiReadResult > > {
1018
- if self . buf . is_empty ( ) {
1019
- return Ok ( Default :: default ( ) ) ;
1020
- }
1031
+ pub fn commit ( & mut self ) -> impl Future < Output = Result < Vec < MultiReadResult > > > + Send + ' _ {
1021
1032
let request = self . build_request ( ) ;
1033
+ Client :: resolve ( self . commit_internally ( request) )
1034
+ }
1035
+
1036
+ fn commit_internally (
1037
+ & self ,
1038
+ request : MarshalledRequest ,
1039
+ ) -> Result < Either < impl Future < Output = Result < Vec < MultiReadResult > > > + Send + ' _ , Vec < MultiReadResult > > > {
1040
+ if request. is_empty ( ) {
1041
+ return Ok ( Right ( Vec :: default ( ) ) ) ;
1042
+ }
1022
1043
let receiver = self . client . send_marshalled_request ( request) ;
1023
- let ( body, _) = receiver. await ?;
1024
- let response = record:: unmarshal :: < Vec < MultiReadResponse > > ( & mut body. as_slice ( ) ) ?;
1025
- let mut results = Vec :: with_capacity ( response. len ( ) ) ;
1026
- for result in response {
1027
- match result {
1028
- MultiReadResponse :: Data { data, stat } => results. push ( MultiReadResult :: Data { data, stat } ) ,
1029
- MultiReadResponse :: Children { children } => results. push ( MultiReadResult :: Children { children } ) ,
1030
- MultiReadResponse :: Error ( err) => results. push ( MultiReadResult :: Error { err } ) ,
1044
+ Ok ( Left ( async move {
1045
+ let ( body, _) = receiver. await ?;
1046
+ let response = record:: unmarshal :: < Vec < MultiReadResponse > > ( & mut body. as_slice ( ) ) ?;
1047
+ let mut results = Vec :: with_capacity ( response. len ( ) ) ;
1048
+ for result in response {
1049
+ match result {
1050
+ MultiReadResponse :: Data { data, stat } => results. push ( MultiReadResult :: Data { data, stat } ) ,
1051
+ MultiReadResponse :: Children { children } => results. push ( MultiReadResult :: Children { children } ) ,
1052
+ MultiReadResponse :: Error ( err) => results. push ( MultiReadResult :: Error { err } ) ,
1053
+ }
1031
1054
}
1032
- }
1033
- Ok ( results )
1055
+ Ok ( results )
1056
+ } ) )
1034
1057
}
1035
1058
1036
1059
/// Clears collected operations.
@@ -1184,30 +1207,49 @@ impl<'a> MultiWriter<'a> {
1184
1207
///
1185
1208
/// # Notable errors
1186
1209
/// * [Error::BadVersion] if check version failed.
1187
- pub async fn commit ( & mut self ) -> std:: result:: Result < Vec < MultiWriteResult > , MultiWriteError > {
1188
- if self . buf . is_empty ( ) {
1189
- return Ok ( Default :: default ( ) ) ;
1190
- }
1210
+ pub fn commit (
1211
+ & mut self ,
1212
+ ) -> impl Future < Output = std:: result:: Result < Vec < MultiWriteResult > , MultiWriteError > > + Send + ' _ {
1191
1213
let request = self . build_request ( ) ;
1214
+ Client :: resolve ( self . commit_internally ( request) )
1215
+ }
1216
+
1217
+ fn commit_internally (
1218
+ & self ,
1219
+ request : MarshalledRequest ,
1220
+ ) -> std:: result:: Result <
1221
+ Either <
1222
+ impl Future < Output = std:: result:: Result < Vec < MultiWriteResult > , MultiWriteError > > + Send + ' _ ,
1223
+ Vec < MultiWriteResult > ,
1224
+ > ,
1225
+ MultiWriteError ,
1226
+ > {
1227
+ if request. is_empty ( ) {
1228
+ return Ok ( Right ( Vec :: default ( ) ) ) ;
1229
+ }
1192
1230
let receiver = self . client . send_marshalled_request ( request) ;
1193
- let ( body, _) = receiver. await ?;
1194
- let response = record:: unmarshal :: < Vec < MultiWriteResponse > > ( & mut body. as_slice ( ) ) ?;
1195
- let failed = response. first ( ) . map ( |r| matches ! ( r, MultiWriteResponse :: Error ( _) ) ) . unwrap_or ( false ) ;
1196
- let mut results = if failed { Vec :: new ( ) } else { Vec :: with_capacity ( response. len ( ) ) } ;
1197
- for ( index, result) in response. into_iter ( ) . enumerate ( ) {
1198
- match result {
1199
- MultiWriteResponse :: Check => results. push ( MultiWriteResult :: Check ) ,
1200
- MultiWriteResponse :: Delete => results. push ( MultiWriteResult :: Delete ) ,
1201
- MultiWriteResponse :: Create { path, stat } => {
1202
- util:: strip_root_path ( path, self . client . chroot . root ( ) ) ?;
1203
- results. push ( MultiWriteResult :: Create { path : path. to_string ( ) , stat } ) ;
1204
- } ,
1205
- MultiWriteResponse :: SetData { stat } => results. push ( MultiWriteResult :: SetData { stat } ) ,
1206
- MultiWriteResponse :: Error ( Error :: UnexpectedErrorCode ( 0 ) ) => { } ,
1207
- MultiWriteResponse :: Error ( err) => return Err ( MultiWriteError :: OperationFailed { index, source : err } ) ,
1231
+ Ok ( Left ( async move {
1232
+ let ( body, _) = receiver. await ?;
1233
+ let response = record:: unmarshal :: < Vec < MultiWriteResponse > > ( & mut body. as_slice ( ) ) ?;
1234
+ let failed = response. first ( ) . map ( |r| matches ! ( r, MultiWriteResponse :: Error ( _) ) ) . unwrap_or ( false ) ;
1235
+ let mut results = if failed { Vec :: new ( ) } else { Vec :: with_capacity ( response. len ( ) ) } ;
1236
+ for ( index, result) in response. into_iter ( ) . enumerate ( ) {
1237
+ match result {
1238
+ MultiWriteResponse :: Check => results. push ( MultiWriteResult :: Check ) ,
1239
+ MultiWriteResponse :: Delete => results. push ( MultiWriteResult :: Delete ) ,
1240
+ MultiWriteResponse :: Create { path, stat } => {
1241
+ util:: strip_root_path ( path, self . client . chroot . root ( ) ) ?;
1242
+ results. push ( MultiWriteResult :: Create { path : path. to_string ( ) , stat } ) ;
1243
+ } ,
1244
+ MultiWriteResponse :: SetData { stat } => results. push ( MultiWriteResult :: SetData { stat } ) ,
1245
+ MultiWriteResponse :: Error ( Error :: UnexpectedErrorCode ( 0 ) ) => { } ,
1246
+ MultiWriteResponse :: Error ( err) => {
1247
+ return Err ( MultiWriteError :: OperationFailed { index, source : err } )
1248
+ } ,
1249
+ }
1208
1250
}
1209
- }
1210
- Ok ( results )
1251
+ Ok ( results )
1252
+ } ) )
1211
1253
}
1212
1254
1213
1255
/// Clears collected operations.
0 commit comments