precedence-net 1.1.0

Create and analyse precedence networks
Documentation
use crate::activity::Activity;
use crate::DurationType;
use crate::Error;
use crate::Result;
use crate::StartType;
use std::hash::{Hash, Hasher};

#[derive(Default, Clone, Debug)]
pub struct ActivityBuilder {
    pub reference: String,
    pub description: String,
    pub minimum_duration: f64,
    pub expected_duration: f64,
    pub maximum_duration: f64,
    pub depth: usize,
    pub start_type: StartType,
    pub duration_type: DurationType,

    pub earliest_start: Option<f64>,
    pub earliest_finish: Option<f64>,
    pub latest_start: Option<f64>,
    pub latest_finish: Option<f64>,
}

impl ActivityBuilder {
    pub fn new(
        refence: &str,
        description: &str,
        expected_duration: f64,
        minimum_duration: f64,
        maximum_duration: f64,
    ) -> ActivityBuilder {
        ActivityBuilder {
            reference: String::from(refence),
            description: String::from(description),
            expected_duration,
            minimum_duration,
            maximum_duration,
            ..Default::default()
        }
    }

    pub(crate) fn build(&self) -> Result<Activity> {
        Ok(Activity {
            reference: self.reference.clone(),
            description: self.description.clone(),
            minimum_duration: self.minimum_duration,
            expected_duration: self.expected_duration,
            maximum_duration: self.maximum_duration,
            start_type: self.start_type,
            duration_type: self.duration_type,
            depth: self.depth,
            earliest_start: self.earliest_start.ok_or(Error::FieldNotSet)?,
            earliest_finish: self.earliest_finish.ok_or(Error::FieldNotSet)?,
            latest_start: self.latest_start.ok_or(Error::FieldNotSet)?,
            latest_finish: self.latest_finish.ok_or(Error::FieldNotSet)?,
        })
    }

    fn mean_duration(&self) -> Result<f64> {
        Ok(((4.0 * self.expected_duration) + self.minimum_duration + self.maximum_duration) / 6.0)
    }

    pub fn duration(&self) -> Result<f64> {
        match self.duration_type {
            DurationType::Expected => Ok(self.expected_duration),
            DurationType::Minimum => Ok(self.minimum_duration),
            DurationType::Maximum => Ok(self.maximum_duration),
            DurationType::Mean => self.mean_duration(),
        }
    }

    pub(crate) fn earliest_start(&mut self, earliest_start: f64) {
        self.earliest_start.replace(earliest_start);
    }

    pub(crate) fn earliest_finish(&mut self, earliest_finish: f64) {
        self.earliest_finish.replace(earliest_finish);
    }

    pub(crate) fn latest_start(&mut self, latest_start: f64) {
        self.latest_start.replace(latest_start);
    }

    pub(crate) fn latest_finish(&mut self, latest_finish: f64) {
        self.latest_finish.replace(latest_finish);
    }

    pub fn expected_duration(&mut self, expected_duration: f64) {
        self.expected_duration = expected_duration;
    }

    pub fn minimum_duration(&mut self, minimum_duration: f64) {
        self.minimum_duration = minimum_duration;
    }

    pub fn maximum_duration(&mut self, maximum_duration: f64) {
        self.maximum_duration = maximum_duration;
    }

    pub fn start_type(&mut self, start_type: StartType) {
        self.start_type = start_type;
    }

    pub fn duration_type(&mut self, duration_type: DurationType) {
        self.duration_type = duration_type;
    }
}

impl Hash for ActivityBuilder {
    fn hash<H: Hasher>(&self, state: &mut H) {
        self.reference.hash(state);
    }
}

impl From<&Activity> for ActivityBuilder {
    fn from(activity: &Activity) -> Self {
        activity.to_builder()
    }
}

impl From<Activity> for ActivityBuilder {
    fn from(activity: Activity) -> Self {
        activity.to_builder()
    }
}