@@ -124,6 +124,18 @@ where
124124/// Result of request execution 
125125pub  type  ExecutionResult < R ,  E >  = Result < ExecutionResponse < R > ,  ExecutionError < E > > ; 
126126
127+ impl < R ,  E >  From < ExecutionResponse < R > >  for  ExecutionResult < R ,  E >  { 
128+     fn  from ( response :  ExecutionResponse < R > )  -> Self  { 
129+         ExecutionResult :: < R ,  E > :: Ok ( response) 
130+     } 
131+ } 
132+ 
133+ impl < R ,  E >  From < ExecutionError < E > >  for  ExecutionResult < R ,  E >  { 
134+     fn  from ( e :  ExecutionError < E > )  -> Self  { 
135+         ExecutionResult :: < R ,  E > :: Err ( e) 
136+     } 
137+ } 
138+ 
127139impl < R ,  E >  IntoInner < Result < R ,  E > >  for  ExecutionResult < R ,  E >  { 
128140    fn  into_inner ( self )  -> Result < R ,  E >  { 
129141        match  self  { 
@@ -145,3 +157,64 @@ where
145157        } 
146158    } 
147159} 
160+ 
161+ /// Convert Result<T,TE> to ExecutionResult<R,E>, taking context from ExecutionResponse. 
162+ pub  trait  WrapToExecutionResult < R ,  RE ,  W > :  Sized  { 
163+     /// Convert self (eg. some [Result]) to [ExecutionResult], taking context information from `W` (eg. ExecutionResponse). 
164+ /// 
165+ /// This function simplifies processing of results by wrapping them into ExecutionResult. 
166+ /// It is useful when you have execution result retrieved in previous step and you want to 
167+ /// add it to the result of the current step. 
168+ /// 
169+ /// Useful when chaining multiple commands and you want to keep track of retries and address. 
170+ /// 
171+ /// ## Example 
172+ /// 
173+ /// ```rust 
174+ /// use rs_dapi_client::{ExecutionResponse, ExecutionResult, WrapToExecutionResult}; 
175+ /// 
176+ /// fn some_request() -> ExecutionResult<i8, String> { 
177+ ///     Ok(ExecutionResponse { 
178+ ///         inner: 42, 
179+ ///         retries: 123, 
180+ ///         address: "http://127.0.0.1".parse().expect("create mock address"), 
181+ ///     }) 
182+ /// } 
183+ /// 
184+ /// fn next_step() -> Result<i32, String> { 
185+ ///     Err("next error".to_string()) 
186+ /// } 
187+ /// 
188+ /// let response = some_request().expect("request should succeed"); 
189+ /// let result: ExecutionResult<i32, String> = next_step().wrap_to_execution_result(&response); 
190+ /// 
191+ /// if let ExecutionResult::Err(error) = result { 
192+ ///    assert_eq!(error.inner, "next error"); 
193+ ///    assert_eq!(error.retries, 123); 
194+ /// } else { 
195+ ///    panic!("Expected error"); 
196+ /// } 
197+ /// ``` 
198+ fn  wrap_to_execution_result ( self ,  result :  & W )  -> ExecutionResult < R ,  RE > ; 
199+ } 
200+ 
201+ impl < R ,  RE ,  TR ,  IR ,  IRE >  WrapToExecutionResult < R ,  RE ,  ExecutionResponse < TR > >  for  Result < IR ,  IRE > 
202+ where 
203+     R :  From < IR > , 
204+     RE :  From < IRE > , 
205+ { 
206+     fn  wrap_to_execution_result ( self ,  result :  & ExecutionResponse < TR > )  -> ExecutionResult < R ,  RE >  { 
207+         match  self  { 
208+             Ok ( r)  => ExecutionResult :: Ok ( ExecutionResponse  { 
209+                 inner :  r. into ( ) , 
210+                 retries :  result. retries , 
211+                 address :  result. address . clone ( ) , 
212+             } ) , 
213+             Err ( e)  => ExecutionResult :: Err ( ExecutionError  { 
214+                 inner :  e. into ( ) , 
215+                 retries :  result. retries , 
216+                 address :  Some ( result. address . clone ( ) ) , 
217+             } ) , 
218+         } 
219+     } 
220+ } 
0 commit comments