TaskFinish#
The finish of one focus task in one evaluated stage. It's an entry of Finish::tasks . It's returned by Project::evaluate and isn't built by hand.
Declaration#
Copy # [ derive ( Clone, Debug, PartialEq ) ]
pub struct TaskFinish {
pub id : Id,
pub finish : Option < Shift> ,
}
With the serde feature (cargo add plen-core --features serde), TaskFinish also implements Serialize and Deserialize, with field names in camelCase.
Fields#
Field
Type
Description
id
Id
The focus task's id, as given in EvaluateOptions::focus .
finish
Option<Shift>
The task's finish date in this stage and its shift from the baseline finish. None when the task isn't in the stage, for example because the candidate removed it.
Example#
Focus on task 2 and score two candidates: one makes task 2 longer, the other removes it.
Copy use plen_core:: {
Candidate, DateTime, EvaluateOptions, Patch, Project, ProjectData, ProjectOptions,
SchedulingChanges, SolveOptions, TaskData, TaskUpdate,
} ;
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 data = ProjectData {
tasks: vec! [ task ( 1 ) , task ( 2 ) ] ,
.. Default :: default( )
} ;
let mut project = Project:: new( ProjectOptions:: default( ) ) ;
project. solve ( Some ( data) , & SolveOptions:: default( ) ) ? ;
let mut longer = SchedulingChanges:: default( ) ;
longer. tasks. update. push ( TaskUpdate {
duration: Patch:: Value( 4. 0 ) ,
.. TaskUpdate:: new( 2 )
} ) ;
let mut drop = SchedulingChanges:: default( ) ;
drop. tasks. remove. push ( 2. into ( ) ) ;
let candidates = [
Candidate { id: " longer" . into ( ) , changes: longer } ,
Candidate { id: " drop" . into ( ) , changes: drop } ,
] ;
let options = EvaluateOptions {
focus: vec! [ 2. into ( ) ] ,
.. Default :: default( )
} ;
let result = project. evaluate ( & candidates, & options) ? ;
for candidate in & result. candidates {
let Some ( scheduled) = & candidate. scheduled else { continue } ;
for task in & scheduled. finish. tasks {
match & task. finish {
Some ( shift) => println! (
" {} : task {} finishes {} , {:+} days" ,
candidate. id, task. id, shift. date, shift. delta
) ,
None => println! ( " {} : task {} not in plan" , candidate. id, task. id) ,
}
}
}
Ok ( ( ) )
}
Output:
Copy longer: task 2 finishes 2026-08-14 08:00, +2 days
drop: task 2 not in plan