]> git.lizzy.rs Git - rust.git/blob - src/libsync/future.rs
Replace all ~"" with "".to_owned()
[rust.git] / src / libsync / future.rs
1 // Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 /*!
12  * A type representing values that may be computed concurrently and
13  * operations for working with them.
14  *
15  * # Example
16  *
17  * ```rust
18  * use sync::Future;
19  * # fn fib(n: uint) -> uint {42};
20  * # fn make_a_sandwich() {};
21  * let mut delayed_fib = Future::spawn(proc() { fib(5000) });
22  * make_a_sandwich();
23  * println!("fib(5000) = {}", delayed_fib.get())
24  * ```
25  */
26
27 #![allow(missing_doc)]
28
29 use std::mem::replace;
30
31 /// A type encapsulating the result of a computation which may not be complete
32 pub struct Future<A> {
33     state: FutureState<A>,
34 }
35
36 enum FutureState<A> {
37     Pending(proc():Send -> A),
38     Evaluating,
39     Forced(A)
40 }
41
42 /// Methods on the `future` type
43 impl<A:Clone> Future<A> {
44     pub fn get(&mut self) -> A {
45         //! Get the value of the future.
46         (*(self.get_ref())).clone()
47     }
48 }
49
50 impl<A> Future<A> {
51     /// Gets the value from this future, forcing evaluation.
52     pub fn unwrap(mut self) -> A {
53         self.get_ref();
54         let state = replace(&mut self.state, Evaluating);
55         match state {
56             Forced(v) => v,
57             _ => fail!( "Logic error." ),
58         }
59     }
60
61     pub fn get_ref<'a>(&'a mut self) -> &'a A {
62         /*!
63         * Executes the future's closure and then returns a reference
64         * to the result.  The reference lasts as long as
65         * the future.
66         */
67         match self.state {
68             Forced(ref v) => return v,
69             Evaluating => fail!("Recursive forcing of future!"),
70             Pending(_) => {
71                 match replace(&mut self.state, Evaluating) {
72                     Forced(_) | Evaluating => fail!("Logic error."),
73                     Pending(f) => {
74                         self.state = Forced(f());
75                         self.get_ref()
76                     }
77                 }
78             }
79         }
80     }
81
82     pub fn from_value(val: A) -> Future<A> {
83         /*!
84          * Create a future from a value.
85          *
86          * The value is immediately available and calling `get` later will
87          * not block.
88          */
89
90         Future {state: Forced(val)}
91     }
92
93     pub fn from_fn(f: proc():Send -> A) -> Future<A> {
94         /*!
95          * Create a future from a function.
96          *
97          * The first time that the value is requested it will be retrieved by
98          * calling the function.  Note that this function is a local
99          * function. It is not spawned into another task.
100          */
101
102         Future {state: Pending(f)}
103     }
104 }
105
106 impl<A:Send> Future<A> {
107     pub fn from_receiver(rx: Receiver<A>) -> Future<A> {
108         /*!
109          * Create a future from a port
110          *
111          * The first time that the value is requested the task will block
112          * waiting for the result to be received on the port.
113          */
114
115         Future::from_fn(proc() {
116             rx.recv()
117         })
118     }
119
120     pub fn spawn(blk: proc():Send -> A) -> Future<A> {
121         /*!
122          * Create a future from a unique closure.
123          *
124          * The closure will be run in a new task and its result used as the
125          * value of the future.
126          */
127
128         let (tx, rx) = channel();
129
130         spawn(proc() {
131             tx.send(blk());
132         });
133
134         Future::from_receiver(rx)
135     }
136 }
137
138 #[cfg(test)]
139 mod test {
140     use future::Future;
141
142     use std::task;
143
144     #[test]
145     fn test_from_value() {
146         let mut f = Future::from_value("snail".to_owned());
147         assert_eq!(f.get(), "snail".to_owned());
148     }
149
150     #[test]
151     fn test_from_receiver() {
152         let (tx, rx) = channel();
153         tx.send("whale".to_owned());
154         let mut f = Future::from_receiver(rx);
155         assert_eq!(f.get(), "whale".to_owned());
156     }
157
158     #[test]
159     fn test_from_fn() {
160         let mut f = Future::from_fn(proc() "brail".to_owned());
161         assert_eq!(f.get(), "brail".to_owned());
162     }
163
164     #[test]
165     fn test_interface_get() {
166         let mut f = Future::from_value("fail".to_owned());
167         assert_eq!(f.get(), "fail".to_owned());
168     }
169
170     #[test]
171     fn test_interface_unwrap() {
172         let f = Future::from_value("fail".to_owned());
173         assert_eq!(f.unwrap(), "fail".to_owned());
174     }
175
176     #[test]
177     fn test_get_ref_method() {
178         let mut f = Future::from_value(22);
179         assert_eq!(*f.get_ref(), 22);
180     }
181
182     #[test]
183     fn test_spawn() {
184         let mut f = Future::spawn(proc() "bale".to_owned());
185         assert_eq!(f.get(), "bale".to_owned());
186     }
187
188     #[test]
189     #[should_fail]
190     fn test_futurefail() {
191         let mut f = Future::spawn(proc() fail!());
192         let _x: ~str = f.get();
193     }
194
195     #[test]
196     fn test_sendable_future() {
197         let expected = "schlorf";
198         let f = Future::spawn(proc() { expected });
199         task::spawn(proc() {
200             let mut f = f;
201             let actual = f.get();
202             assert_eq!(actual, expected);
203         });
204     }
205 }