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
use BoxFuture;
/// Creates an async scope within which you can spawn jobs.
/// This works much like the stdlib's
/// [`scope`](https://doc.rust-lang.org/std/thread/fn.scope.html)
/// function.
///
/// The scope is not considered to be complete until all jobs
/// within the scope have completed. Jobs spawned within the scope
/// can refer to stack variables that are defined outside
/// the scope.
///
/// # Cancellable vs infallible scopes
///
/// By default, moro scopes support *cancellation*,
/// which means that you can cancel the entire scope by invoking
/// `scope.cancel(v)`. Cancellable scopes return a [`Result`] value
/// whose error type is the type of `v`. If your scope does not use `cancel`,
/// you will get compilation errors because the error type cannot be inferred!
///
/// To avoid this, use the `infallible` method on the scope to convert it
/// into a non-cancellable scope:
///
/// ```rust
/// # futures::executor::block_on(async {
/// let scope = moro::async_scope!(|scope| {/* ... */}).await;
/// # });
/// ```
///
/// # Access to stack variables
///
/// Futures spawned inside an async scope can refer to
/// stack variables defined outside the scope:
///
/// ```rust
/// # futures::executor::block_on(async {
/// let r = 22;
/// let scope = moro::async_scope!(|scope| {
/// // OK to refer to `r` here
/// scope.spawn(async { r }).await
/// });
/// let result = scope.await;
/// assert_eq!(result, 22);
/// # });
/// ```
///
/// but when you spawn a future, that future cannot refer to
/// stack variables defined *inside* the scope (except its own
/// variables, of course):
///
/// ```rust,compile_fail,E0373
/// # futures::executor::block_on(async {
/// let scope = moro::async_scope!(|scope| {
/// let r = 22;
//
/// // NOT ok to refer to `r` now, because `r`
/// // is defined inside the scope
/// scope.spawn(async { r }).await
/// });
/// let result = scope.await;
/// assert_eq!(result, 22);
/// # });
/// ```
///
/// # Examples
///
/// ## Hello, world
///
/// The following scope spawns one concurrent task which iterates over
/// the vector `v` and sums its values; the [`infallible`][`Scope::infallible`]
/// method is used to indicate that the scope is never cancelled:
///
/// ```rust
/// # futures::executor::block_on(async {
/// let v = vec![1, 2, 3, 5];
/// let scope = moro::async_scope!(|scope| {
/// let job = scope.spawn(async {
/// let r: i32 = v.iter().sum();
/// r
/// });
/// job.await * 2
/// });
/// let result = scope.await;
/// assert_eq!(result, 22);
/// # });
/// ```
///
/// ## Specifying the result type
///
/// You can use the `->` notation to specify the type of value
/// returned by the scope. This is useful to guide type inference
/// sometimes:
///
/// ```rust
/// # futures::executor::block_on(async {
/// let scope = moro::async_scope!(|scope| -> Result<(), u32> {
/// Err(22) // Ok type would otherwise be unconstrained
/// });
/// let result = scope.await;
/// assert_eq!(result, Err(22));
/// # });
/// ```
///
/// ## More
///
/// For more examples, see the [examples] directory in the
/// repository.
///
/// [examples]: https://github.com/nikomatsakis/structtastic/tree/main/examples
///
pub use Scope;
pub use ScopeBody;
pub use Spawned;
/// Creates a new moro scope. Normally, you invoke this through `moro::async_scope!`.