Roster#

A skill-free inventory of the project's accepted state: its scheduled leaf tasks, its resources and its active assignments. Project::roster returns it. plen_assign::slots builds slots from it.

Note

Roster is native only. It has no serialized form and doesn't implement Serialize, even with the serde feature.

Declaration#

#[derive(Clone, Debug, Default, PartialEq)]
pub struct Roster {
    pub tasks: Vec<Id>,
    pub resources: Vec<Id>,
    pub assignments: Vec<RosterAssignment>,
}

Fields#

Field Type Description
tasks Vec<Id> Scheduled leaf tasks, in model order. Summary tasks and unscheduled tasks aren't listed.
resources Vec<Id> All resources, in model order.
assignments Vec<RosterAssignment> Active assignments, in model order. Assignments on unscheduled tasks aren't listed.

Model order is the order of the entries in the accepted ProjectData.

Example#

The unscheduled task u and its assignment y are left out.

use plen_core::{
    AssignmentData, DateTime, Project, ProjectData, ProjectOptions, ResourceData,
    SolveOptions, TaskData,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 8, 10, 8, 0).ok_or("invalid date")?;
    let booking = |id: &str, task: &str, resource: &str| AssignmentData {
        id: Some(id.into()),
        task: task.into(),
        resource: resource.into(),
        value: 1.0,
        offset: None,
        duration: None,
    };
    let data = ProjectData {
        tasks: vec![
            TaskData { start_date: Some(monday), duration: Some(2.0), ..TaskData::new("a") },
            TaskData {
                start_date: Some(monday),
                duration: Some(1.0),
                unscheduled: true,
                ..TaskData::new("u")
            },
        ],
        resources: ["r1", "r2"]
            .iter()
            .map(|id| ResourceData { id: (*id).into(), capacity: None, calendar_id: None })
            .collect(),
        assignments: vec![booking("x", "a", "r1"), booking("y", "u", "r2")],
        ..Default::default()
    };

    let mut project = Project::new(ProjectOptions::default());
    project.solve(Some(data), &SolveOptions::default())?;

    let roster = project.roster()?;
    for task in &roster.tasks {
        println!("task {task}"); // task a
    }
    for resource in &roster.resources {
        println!("resource {resource}"); // resource r1, resource r2
    }
    for a in &roster.assignments {
        println!("{}: {} on {}", a.id, a.resource, a.task); // x: r1 on a
    }
    Ok(())
}