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
use std::sync::mpsc::Sender;
use std::fmt;
use util::{CargoResult, Fresh, Dirty, Freshness};
pub struct Job { dirty: Work, fresh: Work }
pub struct Work {
inner: Box<FnBox<Sender<String>, CargoResult<()>> + Send>,
}
trait FnBox<A, R> {
fn call_box(self: Box<Self>, a: A) -> R;
}
impl<A, R, F: FnOnce(A) -> R> FnBox<A, R> for F {
fn call_box(self: Box<F>, a: A) -> R {
(*self)(a)
}
}
impl Work {
pub fn new<F>(f: F) -> Work
where F: FnOnce(Sender<String>) -> CargoResult<()> + Send + 'static
{
Work { inner: Box::new(f) }
}
pub fn noop() -> Work {
Work::new(|_| Ok(()))
}
pub fn call(self, tx: Sender<String>) -> CargoResult<()> {
self.inner.call_box(tx)
}
pub fn then(self, next: Work) -> Work {
Work::new(move |tx| {
try!(self.call(tx.clone()));
next.call(tx)
})
}
}
impl Job {
pub fn new(dirty: Work, fresh: Work) -> Job {
Job { dirty: dirty, fresh: fresh }
}
pub fn run(self, fresh: Freshness, tx: Sender<String>) -> CargoResult<()> {
match fresh {
Fresh => self.fresh.call(tx),
Dirty => self.dirty.call(tx),
}
}
}
impl fmt::Debug for Job {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "Job {{ ... }}")
}
}