ResourceOverload#

The overload of one resource in one evaluation stage, paired with its difference from the baseline. It's read from Overload::resources, where it covers the whole stage, and from FocusOverload::resources, where it covers the span of one focus task. Project::evaluate returns it; it isn't built by hand.

Declaration#

#[derive(Clone, Debug, PartialEq)]
pub struct ResourceOverload {
    pub resource: Id,
    pub overload: Amount,
}

With the serde feature (cargo add plen-core --features serde), ResourceOverload also implements Serialize and Deserialize with camelCase field names.

Fields#

Field Type Description
resource Id Id of the resource.
overload Amount value is the sum, over the buckets the container covers, of the load above the resource's capacity, in capacity × buckets. delta is value minus the same sum on the baseline.

Which resources get an entry, and in what order, is set by the container. See Overload and FocusOverload.

Example#

Score a candidate that adds a second assignment for dev1 and print the overload of each resource.

use plen_core::{
    AssignmentData, Candidate, DateTime, EvaluateOptions, Project, ProjectData,
    ProjectOptions, ResourceData, SchedulingChanges, 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 task = |id: i32| TaskData {
        start_date: Some(monday),
        duration: Some(2.0),
        ..TaskData::new(id)
    };
    let assign = |task: i32| AssignmentData {
        id: None,
        task: task.into(),
        resource: "dev1".into(),
        value: 1.0,
        offset: None,
        duration: None,
    };

    let data = ProjectData {
        tasks: vec![task(1), task(2)],
        resources: vec![ResourceData { id: "dev1".into(), capacity: None, calendar_id: None }],
        assignments: vec![assign(1)],
        ..Default::default()
    };

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

    let mut changes = SchedulingChanges::default();
    changes.assignments.add.push(assign(2));
    let candidates = [Candidate { id: "dev1-on-2".into(), changes }];

    let result = project.evaluate(&candidates, &EvaluateOptions::default())?;
    for candidate in &result.candidates {
        let Some(scheduled) = &candidate.scheduled else { continue };
        for entry in &scheduled.overload.resources {
            println!(
                "{}: {} over ({:+} vs baseline)",
                entry.resource, entry.overload.value, entry.overload.delta
            );
        }
    }
    Ok(())
}