1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
//! Classic realization of Future / Promise paradigm
//!
//! # Table of Contents
//! 1. [Introduction](#introduction)
//! 2. [CompletablePromise](#completablepromise)
//! 3. [AsyncPromise](#asyncpromise)
//! 4. [Failures control](#failures-control)
//! 5. [Future combinators](#future-combinators)
//!     1. [map](#map)
//!     2. [flat_map](#flat_map)
//!     3. [recover](#recover)
//!     4. [on_complete](#on_complete)
//!     5. [Example of chaining](#example-of-chaining)
//! 6. [Requirements to V and E](#requirements-to-v-and-e)
//! 7. [Blocking operations](#blocking-operations)
//! 8. [Futures conversion](#futures-conversion)
//! 9. [Pre completed futures](#pre-completed-futures)
//!
//! # Introduction
//!
//! Future is a container for some value which will be received after a certain time but not right
//! after creation. Promise is a function, which produce a value and pass it to a Future. Right
//! after Future receives a value, she calls callback functions, attached by the user, which may
//! transform the value and do some actions with finite result. How Promise calculate a value is
//! not defined. Besides on this, Promise presented as abstract trait Promise<V, E>, which implement
//! specific realizations. Type V presents some success result and E presents an error. In this
//! library exists few predefined realizations of Promise.
//!
//! # CompletablePromise
//!
//! This promise may be completed manually from the user side. Let's see on example.
//!
//! ```
//! let mut p: CompletablePromise<u32, TSafe<Fail + Send>> = CompletablePromise::new();
//! let mut fut = p.future();
//!
//! fut.on_complete(|v| {
//!     println!("Result={}", v.as_ref().ok().unwrap());
//! });
//!
//! thread::spawn(move || {
//!     p.success(100);
//! });
//! ```
//!
//! At first line, new Promise is created. You must explicitly specify him result and error types,
//! because for now, compiler does not may infer it automatically. Next, we extract the Future
//! stored in the Promise. This is exactly that Future which will completes the that promise.
//! At line forth, we attach on_complete callback to the Future. We learn about it later in this
//! doc. At the moment, you must know, that on_complite is called on finite result of the future's
//! chain and accept Result value, which may be as is 'Ok' as is 'Err'. This value represents result
//! of all commutation. For now, in the example code, error value is not produced, and we may simply
//! unwrap 'Ok' result. Next we create new thread and move Promise into it. Further in this another
//! thread, calls success method of Promise. This call, lead to that passed to it value, will be
//! filled to the future, and right after than, on_complete callback will be called. You see
//! 'Result=100' on the your screen.
//!
//! This is not very useful code and it is written only for demonstration, how Promise / Future is
//! works together. In the real world, you may want to perform some  more very complicated actions
//! in the on_complete callback. For example you may perform an http request to a remote server,
//! based on the computation results.
//!
//! # AsyncPromise
//!
//! This promise type accept a closure and executor. Closure will be planned on the specified
//! executor and when it completes, promise will be automatically completes with result of its
//! execution. See to example.
//!
//! ```
//! let task = Box::new(|| Ok(50 + 50));
//!
//! let mut p: AsyncPromise<u32, TSafe<Fail + Send>> =
//!     AsyncPromise::new(task, executor);
//!
//! let mut fut = p.future();
//!
//! fut.on_complete(|v| {
//!     println!("Result={}", v.as_ref().ok().unwrap());
//! });
//! ```
//!
//! First we create the task. Then as in the previous example we create new promise, but now it is
//! AsyncPromise. To the constructor we put task and executor. Right after that, task will be
//! planned to execution on the executor. Next as is earlier, is set on_complete callback. But for
//! now, we don't need to complete the promise manually. This will happen automatically after the
//! task will be completed.
//!
//! This type of promise is most of more usable for various needs. Therefore for him exists special
//! syntactic sugar, which prevents creation of Promise by the user and simply returns prepared and
//! extracted future.
//!
//! ```
//! let mut fut: WrappedFuture<u32, TSafe<Fail + Send>> =
//!     Future::asyncp(task, executor)
//! ```
//!
//! # Failures control
//!
//! Before we talk about futures combinators, need to say about its failures control mechanism. This
//! realization of Future / Promise suggests that at any stage of execution, may occurs some error.
//! It is not panic, but application level error, when programmers consciously creates error
//! precedent. For this, used Result type, which represents the two possible situations - success or
//! failure. Each piece of code executed in the promise / future context must always explicitly
//! specify how it completed - success or with some error. On this is based logic of some
//! combinators, which may be executed only for success or for failed result. Upper type of error
//! specified as E type at promise creation stage.
//!
//! # Future combinators
//!
//! Combinators is a functions which may be attached to the future. They will be called right after
//! future was filled and may transform result with some algorithms. All combinators except of
//! on_complete produce a new future, value of then depends on result of calling attached combinator
//! on parent future. This construction is called - chain of futures. In all the examples, work with
//! the following “future” will be assumed:
//!
//! ```
//! let mut fut: WrappedFuture<u32, TSafe<Fail + Send>> =
//!     Future::asyncp(|| Ok(500 + 500), executor);
//! ```
//!
//! ## map
//!
//! Transforms Ok result of the current future to Ok result of some another type. Never calls if previous
//! result was error.
//!
//! ```
//! fut.map(|v| {
//!       Ok(format!("{}", v))
//! })
//! ```
//!
//! In this example, value of u32 type will be transformed to the result of String type.
//!
//! ## map_err
//!
//! Transforms Err result of the current future to Err result of some another type. Never calls if previous
//! result was Ok.
//!
//! ```
//! fut.map_err(|e| {
//!       Err(OtherErr::new())
//! })
//! ```
//!
//! ## flat_map
//!
//! Transforms result of the current future to another future. Never calls if previous result was
//! error.
//!
//! ```
//! fut.flat_map(move |v| {
//!     let vc = *v;
//!     let fut_inner: WrappedFuture<String, TSafe<Fail + Send>> =
//!     Future::asyncp(move || {
//!         let r = format!("{}", vc + 1000);
//!         Ok(r)
//!     }, executor1.clone());
//!     Ok(fut_inner)
//! });
//! ```
//!
//! In this example we create new future in the flat_map and return in as result. How it work is
//! difficult to understand without understanding of chaining (read about it in the special
//! paragraph). All next combinators which will ba attached after flat_map call, will be attached to
//! the inner future which was returned as result from the flat_map. For example, if you attach map
//! as next combinator, it will accept String type as result with value calculated in the inner
//! future.
//!
//! ## recover
//!
//! Recovers from error if it's occurs at previous stage. Never calls if previous result was success.
//!
//! ```
//! fut.map(|v| {
//!     let err = tsafe!(MyError::ExampleError { text: String::from("Oops!") });
//!     Err(err)
//! }).recover(|e| {
//!     Ok(100)
//! });
//! ```
//! In upper map was produced an error. Recovery combinator handle her and returns some default value
//! as recovery result. Should be noted, than self combinator may produce error. This error will be
//! lifted to a subsequent combinator.
//!
//! ## on_complete
//!
//! Final combinator, because it does not return new future and as consequence of this, you can't
//! unable to extend chain after it.
//!
//! ```
//! fut.on_complete(|v| {
//!     match v {
//!         Ok(result) => println!("Result={}", result),
//!         Err(error) => println!("Error={}", error.lock().unwrap())
//!     }
//! });
//! ```
//!
//! Body of the combinator accepts a raw result of the last future. This may be both success and
//! error and you mast detect who is this.
//!
//! ## Example of chaining
//!
//! Example of how combinators may be chained to work together.
//!
//! ```
//! let vst = 1000;
//!
//! let mut fut: WrappedFuture<u32, TSafe<Fail + Send>> =
//!     Future::asyncp(move || {
//!         if vst > 500 {
//!             Ok(vst + 1000)
//!         } else {
//!             let err: TSafe<Fail + Send> =
//!             tsafe!(MyError::ExampleError { text: String::from("Vst must be > 500!") });
//!             Err(err)
//!         }
//! }, executor.clone());
//!
//! fut.map(|v| {
//!     Ok(format!("{}", *v))
//! }).recover(|e| {
//!     println!("Recovered to default 100 because error occurs -> {}", e.lock().unwrap());
//!     Ok(String::from("100"))
//! }).on_complete(|v| {
//!     println!("Result={}", v.as_ref().unwrap())
//! });
//! ```
//!
//! In this example, depends on value of the vst variable, chain will be executed in two ways. If vst
//! is gross than 500, it will be converted to string and printed at finish. If less, it will
//! case error, which will cause to drop map combinator and call recover. In him we print the message
//! about occurred error, and return default converted to string value 100, which will also be
//! printed at finish.
//!
//! # Requirements to V and E
//!
//! To the types T and E exists some requirements:
//! * Types must not conflict with marker trait Send (Another words, they must be sized)
//! * Types must implements trait Clone
//!
//! Obviously that not all types supports this requirements. Simplest way for get around this
//! restrictions is use interior mutability. If your object is conflicts with Promise type's
//! requirements, simply wrap it to Arc\<Mutex\<T>> and all will be work.
//!
//! # Blocking operations
//!
//! Future have feature for work in fully synchronous way, when the calling thread blocks on waiting
//! on that the future will be completed. Immediately want to warn that this option allowed only in
//! test scenarios and when you need to interact with future from a synchronous code. In all other
//! situations it is a very scary antipattern and his usage may cause to very serious errors in the
//! asynchronous logic. WrappedFuture object presents two synchronous methods.
//!
//! * Ready - waits while future will be completed in a specified timeout. If future was completed
//! before timeout was reached, true will be returned. If timeout occurs, returned false.
//!
//! ```
//! let mut fut1: WrappedFuture<u32, TSafe<Fail + Send>> =
//!     Future::asyncp(|| {
//!         thread::sleep(Duration::from_secs(1));
//!         Ok(100)
//!     }, executor.clone());
//!
//! let ready = fut1.ready(Duration::from_secs(3));
//!
//! match ready {
//!     true => {
//!         match fut1.get_value() {
//!             Ok(value) => {
//!                 println!("fut1 completed with Ok({})", value);
//!             },
//!             Err(error) => {
//!                 println!("fut1 completed with Err({})", error.lock().unwrap());
//!             }
//!         }
//!     },
//!     false => {
//!         println!("fut1 does not completed with timeout");
//!     }
//! }
//! ```
//!
//! * Result - waits while future will be completed in a specified timeout. If future was completed
//!  before timeout was reached, value of future packed in Ok will be returned. If timeout occurs, returned
//!  Err(TimeoutError).
//!
//! ```
//! let mut fut2: WrappedFuture<u32, TSafe<Fail + Send>> =
//!     Future::asyncp(|| {
//!         thread::sleep(Duration::from_secs(1));
//!         Ok(100)
//!     }, executor.clone());
//!
//! let result = fut2.result(Duration::from_secs(3));
//!
//! match result {
//!     Ok(value) => {
//!         match value {
//!             Ok(value) => {
//!                 println!("fut2 completed with Ok({})", value);
//!             },
//!             Err(error) => {
//!                 println!("fut2 completed with Err({})", error.lock().unwrap());
//!             }
//!         }
//!     },
//!     Err(_) => {
//!         println!("fut2 does not completed with timeout");
//!     }
//! }
//! ```
//!
//! Full code of the example you may find in the examples submodule.
//!
//!
//! # Futures conversion
//!
//! Despite the fact that the library futures internally is very different from default Rust futures, it may
//! be simply converted to they. This is possible because both futures type uses identical completion paradigm.
//! For convert sealrs futures to the rust futures, you need implement simple converter. I intentionally did not
//! turn it on to the library in order to don't creates the 'futures' crate versions incompatibility. You may
//! copy this file to anywhere in your project and use it.
//!
//! ```
//! use sealrs::futures::future::WrappedFuture;
//! use futures::future;
//! use futures::{Async, Poll};
//! use std::time::Duration;
//!
//! pub struct SealFuture<V: Send  + Clone + 'static, E: Send  + Clone + 'static> {
//!     fut: WrappedFuture<V, E>
//! }
//!
//! impl <V: Send  + Clone + 'static, E: Send  + Clone + 'static> SealFuture<V, E> {
//!     pub fn new(fut: WrappedFuture<V, E>) -> SealFuture<V, E> {
//!         SealFuture {
//!             fut
//!         }
//!     }
//! }
//!
//! impl <V: Send + Clone, E: Send + Clone> future::Future for SealFuture<V, E> {
//!     type Item = V;
//!     type Error = E;
//!
//!     fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
//!         self.fut.ready(Duration::from_secs(u64::max_value()));
//!
//!         let inner = self.fut.inner.lock().unwrap();
//!         let value = inner.value.as_ref().unwrap();
//!         if value.is_ok() {
//!             let ok_result = value.as_ref().ok().unwrap().clone();
//!             Ok(Async::Ready(ok_result))
//!         } else {
//!             let err_result = value.as_ref().err().unwrap().clone();
//!             Err(err_result)
//!         }
//!     }
//! }
//! ```
//!
//! As example of usage of this converter may be presented json-rpc server based on the 'jsonrpc-http-server' crate.
//! Here requests handler may work in asynchronous mode, in that it return a rust future with expected result
//! instead of a result itself. You may interconnect sealrs future with this server with the following way:
//!
//! ```
//! let mut io = IoHandler::new();
//!
//! io.add_method("say_hello", move |_: Params| {
//!     // Create sealrs future
//!     let fut = Future::asyncp(|| {
//!         Ok(Value::String(format!("hello", v)))
//!     }, (&executor).clone());
//!
//!     // Convert sealrs future to 'futures' future
//!     SealFuture::new(fut)
//! });
//!
//! let server = ServerBuilder::new(io)
//!     .start_http(&"127.0.0.1:3030".parse().unwrap())
//!     .expect("Unable to start RPC server");
//!
//! server.wait();
//! ```
//!
//! Need pay attention that future which will be passed to the converter must be unclosed, which means that the
//! future may contains any sorts of a combinators (map, recover, flat_map and etc.), but not on_complete, because
//! he never returns any result.
//!
//! # Pre completed futures
//!
//! You can creates already completed futures. Such needs may occurs in situation when you needs
//! return some result as future, but you already have expects result. You can create pre completed
//! futures in this way:
//!
//! ```
//! let f1: WrappedFuture<u32, Error> = Future::ok(10);
//! let f2: WrappedFuture<u32, Error> = Future::err(Error::from("xxx"));
//! ```

pub mod future;
pub mod promise;
pub mod completable_promise;
pub mod async_promise;