1
+ #[ doc = "
2
+
3
+ A type representing values that may be computed concurrently and
4
+ operations for working with them.
5
+
6
+ Example:
7
+
8
+ > let delayed_fib = future::spawn {|| fib(5000) };
9
+ > make_a_sandwitch();
10
+ > io::println(#fmt(\" fib(5000) = %?\" , delayed_fib.get()))
11
+
12
+ " ] ;
13
+
14
+ export future;
15
+ export future:: { } ;
16
+ export from_value;
17
+ export from_port;
18
+ export get;
19
+ export with;
20
+ export spawn;
21
+
22
+ import either = either:: t;
23
+
24
+ #[ doc = "The future type" ]
25
+ enum future < A > = {
26
+ mutable v: either<@A , comm:: port<A >>
27
+ } ;
28
+
29
+ #[ doc = "Methods on the `future` type" ]
30
+ impl future < A : send > for future < A > {
31
+
32
+ fn get ( ) -> A {
33
+ #[ doc = "Get the value of the future" ] ;
34
+
35
+ get ( self )
36
+ }
37
+
38
+ fn with < B > ( blk : fn ( A ) -> B ) -> B {
39
+ #[ doc = "Work with the value without copying it" ] ;
40
+
41
+ with ( self , blk)
42
+ }
43
+ }
44
+
45
+ fn from_value < A > ( +val : A ) -> future < A > {
46
+ #[ doc = "
47
+
48
+ Create a future from a value. The value is immediately available
49
+ and calling `get` later will not block.
50
+
51
+ " ] ;
52
+
53
+ future ( {
54
+ mutable v: either:: left ( @val)
55
+ } )
56
+ }
57
+
58
+ fn from_port < A > ( -port : comm:: port < A > ) -> future < A > {
59
+ #[ doc = "
60
+
61
+ Create a future from a port. The first time that the value is
62
+ requested the task will block waiting for the result to be
63
+ received on the port.
64
+
65
+ " ] ;
66
+
67
+ future ( {
68
+ mutable v: either:: right ( port)
69
+ } )
70
+ }
71
+
72
+ fn get < A : send > ( future : future < A > ) -> A {
73
+ #[ doc = "Get the value of the future" ] ;
74
+
75
+ with ( future) { |v| v }
76
+ }
77
+
78
+ fn with < A : send , B > ( future : future < A > , blk : fn ( A ) -> B ) -> B {
79
+ #[ doc = "Work with the value without copying it" ] ;
80
+
81
+ let v = alt future. v {
82
+ either:: left ( v) { v }
83
+ either:: right ( po) {
84
+ let v = @comm:: recv ( po) ;
85
+ future. v = either:: left ( v) ;
86
+ v
87
+ }
88
+ } ;
89
+ blk ( * v)
90
+ }
91
+
92
+ fn spawn < A : send > ( +blk : fn ~( ) -> A ) -> future < A > {
93
+ #[ doc = "
94
+
95
+ Create a future from a unique closure. The closure will be run
96
+ in a new task and its result used as the value of the future.
97
+
98
+ " ] ;
99
+
100
+ let po = comm:: port ( ) ;
101
+ let ch = comm:: chan ( po) ;
102
+ task:: spawn { ||
103
+ comm:: send ( ch, blk ( ) )
104
+ } ;
105
+ from_port ( po)
106
+ }
107
+
108
+ #[ test]
109
+ fn test_from_value ( ) {
110
+ let f = from_value ( "snail" ) ;
111
+ assert get( f) == "snail" ;
112
+ }
113
+
114
+ #[ test]
115
+ fn test_from_port ( ) {
116
+ let po = comm:: port ( ) ;
117
+ let ch = comm:: chan ( po) ;
118
+ comm:: send ( ch, "whale" ) ;
119
+ let f = from_port ( po) ;
120
+ assert get( f) == "whale" ;
121
+ }
122
+
123
+ #[ test]
124
+ fn test_iface_get ( ) {
125
+ let f = from_value ( "fail" ) ;
126
+ assert f. get ( ) == "fail" ;
127
+ }
128
+
129
+ #[ test]
130
+ fn test_with ( ) {
131
+ let f = from_value ( "nail" ) ;
132
+ assert with( f) { |v| v} == "nail" ;
133
+ }
134
+
135
+ #[ test]
136
+ fn test_iface_with ( ) {
137
+ let f = from_value ( "kale" ) ;
138
+ assert f. with { |v| v} == "kale" ;
139
+ }
140
+
141
+ #[ test]
142
+ fn test_spawn ( ) {
143
+ let f = spawn { || "bale" } ;
144
+ assert get( f) == "bale" ;
145
+ }
146
+
147
+ #[ test]
148
+ #[ should_fail]
149
+ #[ ignore( cfg( target_os = "win32" ) ) ]
150
+ fn test_futurefail ( ) {
151
+ let f = spawn { || fail } ;
152
+ let _x: str = get ( f) ;
153
+ }
0 commit comments