ChangeEffects#

The side effects of an applied change set: records removed by a cascade, ids the engine generated, and links or assignments that became inactive. Read it from ApplyReport::effects, returned by Project::apply, to keep your own copy of the data in sync with the project.

Declaration#

#[derive(Clone, Debug, Default, PartialEq)]
pub struct ChangeEffects {
    pub removed_tasks: Vec<Id>,
    pub removed_links: Vec<Id>,
    pub generated_links: Vec<Id>,
    pub dropped_links: Vec<Id>,
    pub removed_assignments: Vec<Id>,
    pub generated_assignments: Vec<Id>,
    pub dropped_assignments: Vec<Id>,
}

With the serde feature, ChangeEffects implements Serialize and Deserialize, with camelCase field names (removedTasks, generatedLinks, ...).

Every list holds ids from applied operations only. A rejected operation adds nothing. Ids appear in the order the operations ran. All lists are empty when the change set had no such effect.

Fields#

Field Type Description
removed_tasks Vec<Id> Tasks deleted from the project.
removed_links Vec<Id> Links deleted from the project.
generated_links Vec<Id> Ids the engine assigned to added links that had no id.
dropped_links Vec<Id> Links that became inactive.
removed_assignments Vec<Id> Assignments deleted from the project.
generated_assignments Vec<Id> Ids the engine assigned to added assignments that had no id.
dropped_assignments Vec<Id> Assignments that became inactive.

removed_tasks#

pub removed_tasks: Vec<Id>

Each task named in tasks.remove, followed by all of its descendants, which are removed with it.

pub removed_links: Vec<Id>

Links named in links.remove, and links removed because their source or target task was removed.

pub generated_links: Vec<Id>

Ids of added links whose LinkAdd::id was None. A generated id has the form $generated_link_1, $generated_link_2, and so on. Use it to update or remove the link later.

pub dropped_links: Vec<Id>

Links that are still in the project but became inactive because of this change set. Links that were already inactive aren't listed. For the cases that drop a link, see LinkData.

removed_assignments#

pub removed_assignments: Vec<Id>

Assignments named in assignments.remove, and assignments removed because their task or resource was removed. A cascaded assignment that has no id isn't listed.

generated_assignments#

pub generated_assignments: Vec<Id>

Ids of added assignments that had no id. A generated id has the form $generated_assignment_1, $generated_assignment_2, and so on.

dropped_assignments#

pub dropped_assignments: Vec<Id>

Assignments that are still in the project but became inactive because of this change set. Assignments that were already inactive aren't listed. For the cases that drop an assignment, see AssignmentData::task.

Example#

Remove task 1, which takes link 10 with it, and add a link without an id:

use plen_core::{
    Changes, DateTime, LinkAdd, LinkData, LinkType, Project, ProjectData, SchedulingChanges,
    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(1.0), ..TaskData::new(1) },
            TaskData { start_date: Some(start), duration: Some(2.0), ..TaskData::new(2) },
            TaskData { start_date: Some(start), duration: Some(3.0), ..TaskData::new(3) },
        ],
        links: vec![LinkData {
            id: 10.into(),
            source: 1.into(),
            target: 2.into(),
            link_type: LinkType::Fs,
            lag: 0.0,
            lag_unit: None,
        }],
        ..Default::default()
    };

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

    let changes = SchedulingChanges {
        tasks: Changes { remove: vec![1.into()], ..Default::default() },
        links: Changes {
            add: vec![LinkAdd {
                id: None,
                source: 2.into(),
                target: 3.into(),
                link_type: LinkType::Fs,
                lag: 0.0,
                lag_unit: None,
            }],
            ..Default::default()
        },
        ..Default::default()
    };

    let effects = project.apply(&changes)?.effects;
    println!("removed tasks: {:?}", effects.removed_tasks); // [Num(1.0)]
    println!("removed links: {:?}", effects.removed_links); // [Num(10.0)]
    println!("new link ids: {:?}", effects.generated_links); // [Str("$generated_link_1")]
    Ok(())
}
  • ApplyReport - carries the effects in effects
  • SchedulingChanges - the change set whose operations cause these effects
  • LinkAdd - an added link without an id gets a generated one here
  • Data Updates - shows how to keep a local copy in sync after apply