Skip to main content

gmt_dos_actors/model/
unknown.rs

1use crate::framework::model::Task;
2
3use super::{Actors, Model, ModelError, Ready, Result, Unknown};
4use std::{marker::PhantomData, time::Instant};
5
6impl Default for Model<Unknown> {
7    fn default() -> Self {
8        Self {
9            name: Default::default(),
10            actors: Default::default(),
11            task_handles: Default::default(),
12            state: Default::default(),
13            start: Instant::now(),
14            verbose: true,
15            elapsed_time: Default::default(),
16        }
17    }
18}
19
20impl FromIterator<Box<dyn Task>> for Model<Unknown> {
21    fn from_iter<T: IntoIterator<Item = Box<dyn Task>>>(iter: T) -> Self {
22        Self {
23            actors: Some(iter.into_iter().collect()),
24            ..Default::default()
25        }
26    }
27}
28
29impl Model<Unknown> {
30    /// Returns a new model
31    pub fn new(actors: Actors) -> Self {
32        Self {
33            name: None,
34            actors: Some(actors),
35            task_handles: None,
36            state: PhantomData,
37            start: Instant::now(),
38            verbose: true,
39            elapsed_time: Default::default(),
40        }
41    }
42    /// Sets the model name
43    pub fn name<S: Into<String>>(self, name: S) -> Self {
44        Self {
45            name: Some(name.into()),
46            ..self
47        }
48    }
49    /// Quiet mode
50    pub fn quiet(mut self) -> Self {
51        self.verbose = false;
52        self
53    }
54    pub fn verbose(mut self,verbose: bool) -> Self {
55        self.verbose = verbose;
56        self
57    }
58    /// Validates actors inputs and outputs
59    pub fn check(self) -> Result<Model<Ready>> {
60        let (n_inputs, n_outputs) = self.n_io();
61        let name = self.name.clone().unwrap_or_default();
62        assert_eq!(
63            n_inputs, n_outputs,
64            "{} I/O #({},{}) don't match, did you forget to add some actors to the model:\n{}",
65            name, n_inputs, n_outputs, self
66        );
67        match self.actors {
68            Some(ref actors) => {
69                let mut inputs_hashes = vec![];
70                let mut outputs_hashes = vec![];
71                for actor in actors {
72                    actor.check_inputs().map_err(Box::new)?;
73                    actor.check_outputs().map_err(Box::new)?;
74                    inputs_hashes.append(&mut actor.inputs_hashes());
75                    outputs_hashes.append(&mut actor.outputs_hashes());
76                }
77                let hashes_diff = outputs_hashes
78                    .into_iter()
79                    .zip(inputs_hashes)
80                    .map(|(o, i)| o as i128 - i as i128)
81                    .sum::<i128>();
82                assert_eq!(hashes_diff,0i128,
83                "{} I/O hashes difference: expected 0, found {}, did you forget to add some actors to the model?",
84                self.name.unwrap_or_default(),
85                hashes_diff);
86                Ok(Model::<Ready> {
87                    name: self.name,
88                    actors: self.actors,
89                    task_handles: None,
90                    state: PhantomData,
91                    start: Instant::now(),
92                    verbose: self.verbose,
93                    elapsed_time: Default::default(),
94                })
95            }
96            None => Err(ModelError::NoActors),
97        }
98    }
99    pub fn skip_check(self) -> Model<Ready> {
100        Model::<Ready> {
101            name: self.name,
102            actors: self.actors,
103            task_handles: None,
104            state: PhantomData,
105            start: Instant::now(),
106            verbose: self.verbose,
107            elapsed_time: Default::default(),
108        }
109    }
110}