AnalyticsStatus#

Tells you whether the engine could compute the analytics you requested. It's the type of the Analytics::status field, which you get in ScheduleResult::analytics when AnalyticsOptions asks for the critical path or slack.

Declaration#

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum AnalyticsStatus {
    Available,
    Invalid,
}

With the serde feature, AnalyticsStatus implements Serialize and Deserialize. Variants are written in kebab-case: "available", "invalid".

Variants#

Variant Serialized Description
Available "available" The analytics were computed. Analytics::critical_path and Analytics::slack hold whatever you requested.
Invalid "invalid" The task graph has a dependency cycle, so the analytics can't be computed. critical_path and slack are both None.

When the status is Invalid, look in ScheduleResult::cycles to find the cycle.

Example#

Request the critical path for two tasks linked in a cycle, then check the status before reading it:

use plen_core::{
    schedule, AnalyticsOptions, AnalyticsStatus, DateTime, LinkData, LinkType, ProjectData,
    SolveOptions, TaskData,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let start = DateTime::from_ymd_hm(2026, 1, 5, 8, 0).ok_or("invalid date")?;
    let mut a = TaskData::new("a");
    a.start_date = Some(start);
    a.duration = Some(1.0);
    let mut b = TaskData::new("b");
    b.start_date = Some(start);
    b.duration = Some(1.0);

    // a -> b -> a: a dependency cycle.
    let link = |id: &str, source: &str, target: &str| LinkData {
        id: id.into(),
        source: source.into(),
        target: target.into(),
        link_type: LinkType::Fs,
        lag: 0.0,
        lag_unit: None,
    };
    let data = ProjectData {
        tasks: vec![a, b],
        links: vec![link("l1", "a", "b"), link("l2", "b", "a")],
        ..Default::default()
    };

    let options = SolveOptions {
        analytics: AnalyticsOptions { critical_path: true, ..Default::default() },
        ..Default::default()
    };
    let result = schedule(data, &options)?;

    if let Some(analytics) = &result.analytics {
        match analytics.status {
            AnalyticsStatus::Available => {
                if let Some(critical) = &analytics.critical_path {
                    println!("critical tasks: {:?}", critical.tasks);
                }
            }
            AnalyticsStatus::Invalid => {
                println!("no analytics: {} cycle(s) in the graph", result.cycles.len());
            }
        }
    }
    Ok(())
}