precedence_net/
activity.rs

1use crate::activity_builder::ActivityBuilder;
2use crate::{DurationType, StartType};
3use std::hash::{Hash, Hasher};
4
5#[derive(Clone, Debug)]
6pub struct Activity {
7    pub reference: String,
8    pub description: String,
9    pub minimum_duration: f64,
10    pub expected_duration: f64,
11    pub maximum_duration: f64,
12    pub start_type: StartType,
13    pub duration_type: DurationType,
14    pub depth: usize,
15
16    pub earliest_start: f64,
17    pub earliest_finish: f64,
18    pub latest_start: f64,
19    pub latest_finish: f64,
20}
21
22pub(crate) const START_REFERENCE: &str = "precedence_net_crate_start";
23pub(crate) const FINISH_REFERENCE: &str = "precedence_net_crate_finish";
24
25impl Activity {
26    pub(crate) fn mean_duration(&self) -> f64 {
27        ((4.0 * self.expected_duration) + self.minimum_duration + self.maximum_duration) / 6.0
28    }
29
30    pub(crate) fn standard_deviation(&self) -> f64 {
31        (self.maximum_duration - self.minimum_duration) / 6.0
32    }
33
34    pub(crate) fn variance(&self) -> f64 {
35        self.standard_deviation().powi(2)
36    }
37
38    pub(crate) fn duration(&self) -> f64 {
39        match self.duration_type {
40            DurationType::Expected => self.expected_duration,
41            DurationType::Maximum => self.maximum_duration,
42            DurationType::Minimum => self.minimum_duration,
43            DurationType::Mean => self.mean_duration(),
44        }
45    }
46
47    pub(crate) fn on_critical_path(&self) -> bool {
48        self.latest_start == self.earliest_start
49    }
50
51    pub(crate) fn total_float(&self) -> f64 {
52        self.latest_finish - self.earliest_finish
53    }
54
55    pub(crate) fn start(&self) -> f64 {
56        match self.start_type {
57            StartType::Earliest => self.earliest_start,
58            StartType::Latest => self.latest_start,
59        }
60    }
61
62    pub(crate) fn finish(&self) -> f64 {
63        match self.start_type {
64            StartType::Earliest => self.earliest_finish,
65            StartType::Latest => self.latest_finish,
66        }
67    }
68
69    pub(crate) fn active_on(&self, time: f64) -> bool {
70        (self.start()..self.finish()).contains(&time)
71    }
72
73    pub(crate) fn active_during(&self, range: std::ops::Range<f64>) -> bool {
74        !(self.finish() <= range.start || self.start() >= range.end)
75    }
76
77    pub(crate) fn to_builder(&self) -> ActivityBuilder {
78        ActivityBuilder {
79            reference: self.reference.clone(),
80            description: self.description.clone(),
81            minimum_duration: self.minimum_duration,
82            expected_duration: self.expected_duration,
83            maximum_duration: self.maximum_duration,
84            depth: self.depth,
85            start_type: self.start_type,
86            duration_type: self.duration_type,
87
88            earliest_start: None,
89            earliest_finish: None,
90            latest_start: None,
91            latest_finish: None,
92        }
93    }
94}
95
96impl Hash for Activity {
97    fn hash<H: Hasher>(&self, state: &mut H) {
98        self.reference.hash(state);
99    }
100}
101
102impl TryFrom<&ActivityBuilder> for Activity {
103    type Error = crate::Error;
104
105    fn try_from(activity_builder: &ActivityBuilder) -> std::result::Result<Activity, Self::Error> {
106        activity_builder.build()
107    }
108}
109
110impl TryFrom<ActivityBuilder> for Activity {
111    type Error = crate::Error;
112
113    fn try_from(activity_builder: ActivityBuilder) -> std::result::Result<Activity, Self::Error> {
114        activity_builder.build()
115    }
116}