[Canonical page](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/evaluate-result/>)
[Full documentation index](<https://docs.dhtmlx.com/planning-engine/llms.txt>)


# EvaluateResult

The result of [`Project::evaluate`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#evaluate>) and [`Project::evaluate_with`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#evaluate_with>). It holds the metrics of the reference state and one [`CandidateResult`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/candidate-result.md>) per submitted [`Candidate`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/candidate.md>), all scored against the same baseline.

## Declaration

```rust
#[derive(Clone, Debug, PartialEq)]
pub struct EvaluateResult {
    pub baseline_id: String,
    pub baseline: Metrics,
    pub candidates: Vec<CandidateResult>,
}
```

With the `serde` feature, `EvaluateResult` implements `Serialize` and `Deserialize` with camelCase field names (`baselineId`).

## Fields

| Field | Type | Description |
|---|---|---|
| `baseline_id` | `String` | Id of the accepted baseline the candidates were scored against. With [`EvaluateOptions::clear_first`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/evaluate-options.md#clear_first>), it's still the accepted state's id, not the cleared copy's. |
| `baseline` | [`Metrics`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/metrics.md>) | Metrics of the reference state itself. Every `delta` in it is `0`. The reference state is the accepted state, or its cleared copy when `clear_first` is set. |
| `candidates` | `Vec<`[`CandidateResult`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/candidate-result.md>)`>` | One entry per candidate, in input order. |

Rank candidates by [`CandidateResult::cost`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/candidate-result.md>) against `baseline.cost`.

## Example

Score moving task 2 from `dev1` to `dev2`.

```rust
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 result = project.evaluate(&candidates, &EvaluateOptions::default())?;
    println!("baseline {}: cost {}", result.baseline_id, result.baseline.cost); // cost 2
    for candidate in &result.candidates {
        match (&candidate.error, candidate.cost) {
            (Some(error), _) => println!("{}: rejected at {}", candidate.id, error.path),
            (None, Some(cost)) => println!("{}: cost {cost}", candidate.id), // dev2: cost 0
            (None, None) => {}
        }
    }
    Ok(())
}
```

## Related

- [`Project::evaluate`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#evaluate>) - the call that returns it
- [`EvaluateOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/evaluate-options.md>) - the options that shape the result
- [`Metrics`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/evaluate/metrics.md>) - the measurements of the baseline and each candidate stage
- [Evaluating Alternatives](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/evaluating-alternatives.md#comparing-candidates>) - how to rank candidates from the result
- [Serialize results to JSON](<https://docs.dhtmlx.com/planning-engine/rust/how-to/serialize-results-to-json.md>) - sending the result to a client
