use crate::activity_builder::ActivityBuilder;
use crate::{DurationType, StartType};
use std::hash::{Hash, Hasher};
#[derive(Clone, Debug)]
pub struct Activity {
pub reference: String,
pub description: String,
pub minimum_duration: f64,
pub expected_duration: f64,
pub maximum_duration: f64,
pub start_type: StartType,
pub duration_type: DurationType,
pub depth: usize,
pub earliest_start: f64,
pub earliest_finish: f64,
pub latest_start: f64,
pub latest_finish: f64,
}
pub(crate) const START_REFERENCE: &str = "precedence_net_crate_start";
pub(crate) const FINISH_REFERENCE: &str = "precedence_net_crate_finish";
impl Activity {
pub(crate) fn mean_duration(&self) -> f64 {
((4.0 * self.expected_duration) + self.minimum_duration + self.maximum_duration) / 6.0
}
pub(crate) fn standard_deviation(&self) -> f64 {
(self.maximum_duration - self.minimum_duration) / 6.0
}
pub(crate) fn variance(&self) -> f64 {
self.standard_deviation().powi(2)
}
pub(crate) fn duration(&self) -> f64 {
match self.duration_type {
DurationType::Expected => self.expected_duration,
DurationType::Maximum => self.maximum_duration,
DurationType::Minimum => self.minimum_duration,
DurationType::Mean => self.mean_duration(),
}
}
pub(crate) fn on_critical_path(&self) -> bool {
self.latest_start == self.earliest_start
}
pub(crate) fn total_float(&self) -> f64 {
self.latest_finish - self.earliest_finish
}
pub(crate) fn start(&self) -> f64 {
match self.start_type {
StartType::Earliest => self.earliest_start,
StartType::Latest => self.latest_start,
}
}
pub(crate) fn finish(&self) -> f64 {
match self.start_type {
StartType::Earliest => self.earliest_finish,
StartType::Latest => self.latest_finish,
}
}
pub(crate) fn active_on(&self, time: f64) -> bool {
(self.start()..self.finish()).contains(&time)
}
pub(crate) fn active_during(&self, range: std::ops::Range<f64>) -> bool {
!(self.finish() <= range.start || self.start() >= range.end)
}
pub(crate) fn to_builder(&self) -> ActivityBuilder {
ActivityBuilder {
reference: self.reference.clone(),
description: self.description.clone(),
minimum_duration: self.minimum_duration,
expected_duration: self.expected_duration,
maximum_duration: self.maximum_duration,
depth: self.depth,
start_type: self.start_type,
duration_type: self.duration_type,
earliest_start: None,
earliest_finish: None,
latest_start: None,
latest_finish: None,
}
}
}
impl Hash for Activity {
fn hash<H: Hasher>(&self, state: &mut H) {
self.reference.hash(state);
}
}
impl TryFrom<&ActivityBuilder> for Activity {
type Error = crate::Error;
fn try_from(activity_builder: &ActivityBuilder) -> std::result::Result<Activity, Self::Error> {
activity_builder.build()
}
}
impl TryFrom<ActivityBuilder> for Activity {
type Error = crate::Error;
fn try_from(activity_builder: ActivityBuilder) -> std::result::Result<Activity, Self::Error> {
activity_builder.build()
}
}