precedence_net/
activity.rs1use 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}