SolveOptions#

Options for Project::solve and schedule. They set which part of the project is scheduled and which extra data the ScheduleResult carries. SolveOptions::default() schedules the whole project and returns only the changed tasks.

Declaration#

#[derive(Clone, Debug, Default, PartialEq)]
pub struct SolveOptions {
    pub subtree: Option<Subtree>,
    pub analytics: AnalyticsOptions,
    pub reasons: bool,
    pub include_unchanged: bool,
}

All fields are public. Set the ones you need with struct update syntax: SolveOptions { reasons: true, ..Default::default() }.

For how Project::solve uses these options to reuse its cached result, see Project::solve.

Fields#

Field Type Default Description
subtree Option<Subtree> None Schedules only one task's subtree and the tasks that depend on it. None schedules the whole project.
analytics AnalyticsOptions no analytics Requests critical path and slack. Fills ScheduleResult::analytics.
reasons bool false Fills Mutation::reason on each update with the Reason the task moved.
include_unchanged bool false Also reports unchanged tasks in ScheduleResult::updates, so the result holds the full date list.

subtree#

pub subtree: Option<Subtree>

Limits scheduling to the scope the Subtree value describes. Build the value with Subtree::new.

analytics#

pub analytics: AnalyticsOptions

Turns on AnalyticsOptions::slack and AnalyticsOptions::critical_path. With both flags false (the default), ScheduleResult::analytics is None. With either flag set, it's Some(Analytics); check Analytics::status before reading the data.

reasons#

pub reasons: bool

When true, each Mutation in updates carries a Reason in its reason field. When false, reason is always None.

Mutation::reason lists when it stays None.

include_unchanged#

pub include_unchanged: bool

When false, updates holds only the tasks the solve changed or that edits touched. When true, updates also holds every scheduled task that didn't change, each with start_date, end_date and duration set. This gives the full normalized date list on initial load.

  • Every scheduled task is reported: leaves, summaries and milestones. Unscheduled tasks are never reported.
  • With subtree, every task in the subtree is reported, ancestors of subtree tasks included, plus the usual changed or touched updates outside the subtree.
  • On a project with cycles, every scheduled task is reported in model order (subtree is ignored), with its stored dates and durations.
  • leveling_delay and pauses never appear in these entries.

The extra entries don't affect ScheduleResult::baseline_id, which follows real date changes only. Every other result field matches what the same solve returns with include_unchanged: false.

Example#

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

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 1, 5, 8, 0).ok_or("invalid date")?;

    let mut design = TaskData::new("design");
    design.start_date = Some(monday);
    design.duration = Some(2.0);

    let mut build = TaskData::new("build");
    build.start_date = Some(monday);
    build.duration = Some(3.0);

    let data = ProjectData {
        tasks: vec![design, build],
        links: vec![LinkData {
            id: "l1".into(),
            source: "design".into(),
            target: "build".into(),
            link_type: LinkType::Fs,
            lag: 0.0,
            lag_unit: None,
        }],
        ..Default::default()
    };

    let options = SolveOptions {
        analytics: AnalyticsOptions {
            critical_path: true,
            ..Default::default()
        },
        reasons: true,
        include_unchanged: true,
        ..Default::default()
    };

    let mut project = Project::default();
    let result = project.solve(Some(data), &options)?;

    // Every scheduled task, changed or not.
    for update in &result.updates {
        if let (Some(start), Some(end)) = (update.start_date, update.end_date) {
            println!("{}: {} - {} ({:?})", update.id, start, end, update.reason);
        }
    }
    Ok(())
}

For step-by-step use, see Load all task dates and Reschedule a branch.