assemble_core/task/
up_to_date.rs

1use crate::{Executable, Task};
2use std::fmt::{Debug, Formatter};
3
4/// Can check if this value is up to date.
5pub trait UpToDate {
6    /// Whether this value is up to date.
7    ///
8    /// By default, everything is always not up to date.
9    fn up_to_date(&self) -> bool {
10        true
11    }
12}
13
14assert_obj_safe!(UpToDate);
15
16pub struct UpToDateHandler<'h, T: Task> {
17    container: &'h Vec<Box<dyn Fn(&Executable<T>) -> bool + Send + Sync>>,
18    exec: &'h Executable<T>,
19}
20
21impl<'h, T: Task> UpToDate for UpToDateHandler<'h, T> {
22    fn up_to_date(&self) -> bool {
23        for check in self.container {
24            if !check(self.exec) {
25                return false;
26            }
27        }
28        true
29    }
30}
31
32/// Contains up to date checks for a task
33pub struct UpToDateContainer<T: Task> {
34    extra_checks: Vec<Box<dyn Fn(&Executable<T>) -> bool + Send + Sync>>,
35}
36
37impl<T: Task> Default for UpToDateContainer<T> {
38    fn default() -> Self {
39        Self {
40            extra_checks: vec![],
41        }
42    }
43}
44
45impl<T: Task> Debug for UpToDateContainer<T> {
46    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
47        f.debug_struct("UpToDateContainer")
48            .field("len", &self.extra_checks.len())
49            .finish()
50    }
51}
52
53impl<T: Task> UpToDateContainer<T> {
54    /// Add an up to date check
55    pub fn up_to_date_if<F>(&mut self, spec: F)
56    where
57        F: Fn(&Executable<T>) -> bool,
58        F: 'static + Send + Sync,
59    {
60        self.extra_checks.push(Box::new(spec))
61    }
62
63    pub fn handler<'h>(&'h self, exec: &'h Executable<T>) -> UpToDateHandler<'h, T> {
64        UpToDateHandler {
65            container: &self.extra_checks,
66            exec,
67        }
68    }
69
70    pub fn len(&self) -> usize {
71        self.extra_checks.len()
72    }
73}