SchedulingConfig#

Project-wide scheduling settings. It's the config field of ProjectData, so it travels with every snapshot passed to schedule, Project::solve or Project::analyze. SchedulingConfig::default() gives the defaults listed below; set only the fields you need and fill the rest with ..Default::default().

Declaration#

#[derive(Clone, Debug)]
pub struct SchedulingConfig {
    pub apply_constraints: bool,
    pub schedule_from_end: bool,
    pub gap_behavior: GapBehavior,
    pub move_projects: bool,
    pub project_constraint: bool,
    pub group_mode: bool,
    pub use_progress: bool,
    pub descendant_links: bool,
    pub calendar_mode: CalendarMode,
    pub strict_calendar: bool,
    pub max_iterations: u32,
    pub project_start: Option<DateTime>,
    pub project_end: Option<DateTime>,
    pub duration_unit: TimeUnit,
    pub use_calendars: bool,
    pub default_resource_capacity: f64,
    pub root_id: Id,
}

impl Default for SchedulingConfig { /* … */ }

Fields#

apply_constraints#

pub apply_constraints: bool

Enables task constraints (ConstraintType) as hard bounds. With false, constraints are ignored.

Default: false.

schedule_from_end#

pub schedule_from_end: bool

Plans the project backward (ALAP) from its end instead of forward (ASAP) from its start. Project::level rejects a project with this set.

Default: false.

gap_behavior#

pub gap_behavior: GapBehavior

Whether tasks keep their current dates where links allow (Preserve) or move to the earliest position (Compress).

Default: GapBehavior::Preserve.

move_projects#

pub move_projects: bool

true moves a summary and its descendants as one block. false schedules the summary's leaves individually, keeping their offsets within the summary.

Default: true.

project_constraint#

pub project_constraint: bool

A child task without its own constraint inherits its parent's constraint. Has no effect while group_mode is true.

Default: false.

group_mode#

pub group_mode: bool

Turns off the constraint inheritance of project_constraint. It has no other effect.

Default: false.

use_progress#

pub use_progress: bool

Treats a task with progress == 1 as completed: it keeps its dates.

Default: false.

pub descendant_links: bool

Allows links between a summary and its own descendant. With false, such a link is dropped and reported in the result's notes.

Default: false.

calendar_mode#

pub calendar_mode: CalendarMode

Which calendars place the work: resource calendars (Resource) or task calendars only (Task, TaskInherited).

Default: CalendarMode::Resource.

strict_calendar#

pub strict_calendar: bool

Reports a Conflict::CalendarNonWorking when a moving summary block lands a task on non-working time.

Default: false.

max_iterations#

pub max_iterations: u32

Upper limit on scheduling passes. Must be at least 1.

Default: 8.

project_start#

pub project_start: Option<DateTime>

Earliest date of the project: no task starts before it. Also the date source for tasks that have no dates of their own.

Default: None.

project_end#

pub project_end: Option<DateTime>

Upper bound of the project, used by backward (schedule_from_end) plans.

Default: None.

duration_unit#

pub duration_unit: TimeUnit

Unit of task duration and link lag. A task can override it with its own TaskData::duration_unit.

Default: TimeUnit::Day.

use_calendars#

pub use_calendars: bool

true schedules on working calendars. false treats every calendar as working time around the clock.

Default: true.

default_resource_capacity#

pub default_resource_capacity: f64

Capacity of a resource that doesn't set its own, in assignment value units (1.0 = 100 %). Must be finite and non-negative.

Default: 1.0.

root_id#

pub root_id: Id

A task parent equal to this id (or "") means the task has no parent. Ids compare as normalized keys, so the default matches both 0 and "0". On ingress such a parent is stored as no parent. Set it when your data uses another root id, such as -1 or "root"; a task with id 0 is then an ordinary parent.

Default: Id::Num(0.0).

Errors#

The config is checked when the snapshot is imported. Both Validation modes reject these values with Error::Input, reported at the field path:

Path When it occurs
config.max_iterations max_iterations is 0
config.default_resource_capacity the value is negative, NaN or infinite

Example#

use plen_core::{
    schedule, DateTime, ProjectData, SchedulingConfig, SolveOptions, TaskData, TimeUnit,
};

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

    let mut task = TaskData::new("a");
    task.start_date = Some(start);
    task.duration = Some(16.0);

    let data = ProjectData {
        config: SchedulingConfig {
            duration_unit: TimeUnit::Hour,
            apply_constraints: true,
            project_start: Some(start),
            ..Default::default()
        },
        tasks: vec![task],
        ..Default::default()
    };

    let result = schedule(
        data,
        &SolveOptions {
            include_unchanged: true,
            ..Default::default()
        },
    )?;
    println!("{:?}", result.updates[0].end_date);
    Ok(())
}