ProjectData#

One complete snapshot of a project: its scheduling config, calendars, tasks, links, resources and assignments. It's passed by value to Project::solve and schedule, and by reference to Project::analyze. ProjectData is an import format: the project keeps its own normalized copy, and later edits go through SchedulingChanges, not through this struct.

Build it with a struct literal and ..Default::default(). Every collection except tasks usually stays empty.

Declaration#

#[derive(Clone, Debug, Default)]
pub struct ProjectData {
    pub config: SchedulingConfig,
    pub calendars: Vec<CalendarData>,
    pub tasks: Vec<TaskData>,
    pub links: Vec<LinkData>,
    pub resources: Vec<ResourceData>,
    pub assignments: Vec<AssignmentData>,
}

Fields#

Field Type Default Description
config SchedulingConfig SchedulingConfig::default() Project-wide scheduling settings.
calendars Vec<CalendarData> empty Working-time calendars. Empty means only the built-in "global" calendar (Mon-Fri, 08:00-12:00 and 13:00-17:00). A calendar with id "global" replaces the built-in one.
tasks Vec<TaskData> empty Tasks, summaries and milestones. Hierarchy comes from each task's parent.
links Vec<LinkData> empty Dependencies between tasks.
resources Vec<ResourceData> empty Resources that assignments book.
assignments Vec<AssignmentData> empty Bookings of a resource on a task.

Validation#

Under the default Validation::Strict, the rules below tie the collections together. A broken rule returns Err(Error::Input) with the path of the offending field. Rules for a single record are on that record's page.

Rule Error path
Task ids are unique tasks[i].id
Link ids are unique links[i].id
Calendar ids are unique calendars[i]
Resource ids are unique resources[i].id
Assignment ids are unique assignments[i].id
A task's parent names a task in tasks (or equals config.root_id) tasks[i].parent
A task's calendar_id names a calendar in calendars or "global" tasks[i].calendar_id
A resource's calendar_id names a calendar (checked only in CalendarMode::Resource) resources[i].calendar_id
An assignment's task names a task in tasks assignments[i].task
An assignment's resource names a resource in resources assignments[i].resource

Uniqueness follows Id equality.

Some references don't fail validation. They drop the record instead and report a Note in the result; see Note::DroppedLink and Note::DroppedAssignment for the cases.

Validation::Repair fixes some of these cases instead of rejecting them.

Example#

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

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

    let data = ProjectData {
        tasks: vec![
            TaskData {
                start_date: Some(start),
                duration: Some(2.0),
                ..TaskData::new(1)
            },
            TaskData {
                start_date: Some(start),
                duration: Some(3.0),
                ..TaskData::new(2)
            },
        ],
        links: vec![LinkData {
            id: 1.into(),
            source: 1.into(),
            target: 2.into(),
            link_type: LinkType::Fs,
            lag: 0.0,
            lag_unit: None,
        }],
        ..Default::default()
    };

    let result = schedule(data, &SolveOptions::default())?;
    for update in &result.updates {
        println!("{update:?}");
    }
    Ok(())
}