Finish#
The finish dates of one evaluation stage: the project finish and the finish of each focus task, each with its distance from the baseline. You read it from Metrics::finish , which appears in EvaluateResult::baseline and in the scheduled and leveled stages of every CandidateResult .
Declaration#
Copy # [ derive ( Clone, Debug, PartialEq ) ]
pub struct Finish {
pub project : Option < Shift> ,
pub tasks : Vec < TaskFinish> ,
}
With the serde feature, Finish implements Serialize and Deserialize with camelCase field names.
Fields#
Field
Type
Description
project
Option<Shift>
Project finish: the latest end over the scheduled tasks of this stage. None when the stage has no tasks.
tasks
Vec<TaskFinish>
One entry per id in EvaluateOptions::focus , in the same order. Empty when focus is empty.
Shift describes how delta is measured. TaskFinish covers a focus task that the candidate removed.
Example#
Report the project finish and the finish of task 2 for a candidate that moves task 2 to dev2.
Copy use plen_core:: {
AssignmentData, AssignmentUpdate, Candidate, DateTime, EvaluateOptions, Patch, 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 resource = | id : & str | ResourceData {
id: id. into ( ) ,
capacity: None ,
calendar_id: None ,
} ;
let assignment = | id : & str , task : i32 | AssignmentData {
id: Some ( id. into ( ) ) ,
task: task. into ( ) ,
resource: " dev1" . into ( ) ,
value: 1. 0 ,
offset: None ,
duration: None ,
} ;
let data = ProjectData {
tasks: vec! [ task ( 1 ) , task ( 2 ) ] ,
resources: vec! [ resource ( " dev1" ) , resource ( " dev2" ) ] ,
assignments: vec! [ assignment ( " a1" , 1 ) , assignment ( " a2" , 2 ) ] ,
.. Default :: default( )
} ;
let mut project = Project:: new( ProjectOptions:: default( ) ) ;
project. solve ( Some ( data) , & SolveOptions:: default( ) ) ? ;
let mut changes = SchedulingChanges:: default( ) ;
let mut to_dev2 = AssignmentUpdate:: new( " a2" ) ;
to_dev2. resource = Patch:: Value( " dev2" . into ( ) ) ;
changes. assignments. update. push ( to_dev2) ;
let candidates = [ Candidate { id: " dev2" . into ( ) , changes } ] ;
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 } ;
let finish = & scheduled. finish;
if let Some ( shift) = & finish. project {
println! ( " {} : project ends {} ({:+} )" , candidate. id, shift. date, shift. delta) ;
}
for task in & finish. tasks {
match & task. finish {
Some ( shift) => println! ( " task {} ends {} ({:+} )" , task. id, shift. date, shift. delta) ,
None => println! ( " task {} removed" , task. id) ,
}
}
}
Ok ( ( ) )
}