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


# SolveOptions

Options for [`Project::solve`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#solve>) and [`schedule`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/schedule.md>). They set which part of the project is scheduled and which extra data the [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/schedule-result.md>) carries. `SolveOptions::default()` schedules the whole project and returns only the changed tasks.

## Declaration

```rust
#[derive(Clone, Debug, Default, PartialEq)]
pub struct SolveOptions {
    pub subtree: Option<Subtree>,
    pub analytics: AnalyticsOptions,
    pub reasons: bool,
    pub include_unchanged: bool,
}
```

All fields are public. Set the ones you need with struct update syntax: `SolveOptions { reasons: true, ..Default::default() }`.

For how `Project::solve` uses these options to reuse its cached result, see [`Project::solve`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#solve>).

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `subtree` | `Option<`[`Subtree`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/subtree.md>)`>` | `None` | Schedules only one task's subtree and the tasks that depend on it. `None` schedules the whole project. |
| `analytics` | [`AnalyticsOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/analytics-options.md>) | no analytics | Requests critical path and slack. Fills [`ScheduleResult::analytics`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/schedule-result.md#analytics>). |
| `reasons` | `bool` | `false` | Fills [`Mutation::reason`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) on each update with the [`Reason`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/reason.md>) the task moved. |
| `include_unchanged` | `bool` | `false` | Also reports unchanged tasks in `ScheduleResult::updates`, so the result holds the full date list. |

### subtree

```rust
pub subtree: Option<Subtree>
```

Limits scheduling to the scope the [`Subtree`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/subtree.md>) value describes. Build the value with [`Subtree::new`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/subtree.md#new>).

### analytics

```rust
pub analytics: AnalyticsOptions
```

Turns on [`AnalyticsOptions::slack`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/analytics-options.md>) and [`AnalyticsOptions::critical_path`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/analytics-options.md>). With both flags `false` (the default), `ScheduleResult::analytics` is `None`. With either flag set, it's `Some(`[`Analytics`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/analytics.md>)`)`; check [`Analytics::status`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/analytics-status.md>) before reading the data.

### reasons

```rust
pub reasons: bool
```

When `true`, each [`Mutation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) in `updates` carries a [`Reason`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/reason.md>) in its `reason` field. When `false`, `reason` is always `None`.

[`Mutation::reason`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) lists when it stays `None`.

### include_unchanged

```rust
pub include_unchanged: bool
```

When `false`, `updates` holds only the tasks the solve changed or that edits touched. When `true`, `updates` also holds every scheduled task that didn't change, each with `start_date`, `end_date` and `duration` set. This gives the full normalized date list on initial load.

- Every scheduled task is reported: leaves, summaries and milestones. Unscheduled tasks are never reported.
- With `subtree`, every task in the subtree is reported, ancestors of subtree tasks included, plus the usual changed or touched updates outside the subtree.
- On a project with cycles, every scheduled task is reported in model order (`subtree` is ignored), with its stored dates and durations.
- `leveling_delay` and `pauses` never appear in these entries.

The extra entries don't affect `ScheduleResult::baseline_id`, which follows real date changes only. Every other result field matches what the same solve returns with `include_unchanged: false`.

## Example

```rust
use plen_core::{
    AnalyticsOptions, DateTime, LinkData, LinkType, Project, ProjectData, SolveOptions, TaskData,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 1, 5, 8, 0).ok_or("invalid date")?;

    let mut design = TaskData::new("design");
    design.start_date = Some(monday);
    design.duration = Some(2.0);

    let mut build = TaskData::new("build");
    build.start_date = Some(monday);
    build.duration = Some(3.0);

    let data = ProjectData {
        tasks: vec![design, build],
        links: vec![LinkData {
            id: "l1".into(),
            source: "design".into(),
            target: "build".into(),
            link_type: LinkType::Fs,
            lag: 0.0,
            lag_unit: None,
        }],
        ..Default::default()
    };

    let options = SolveOptions {
        analytics: AnalyticsOptions {
            critical_path: true,
            ..Default::default()
        },
        reasons: true,
        include_unchanged: true,
        ..Default::default()
    };

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

    // Every scheduled task, changed or not.
    for update in &result.updates {
        if let (Some(start), Some(end)) = (update.start_date, update.end_date) {
            println!("{}: {} - {} ({:?})", update.id, start, end, update.reason);
        }
    }
    Ok(())
}
```

For step-by-step use, see [Load all task dates](<https://docs.dhtmlx.com/planning-engine/rust/how-to/load-all-task-dates.md>) and [Reschedule a branch](<https://docs.dhtmlx.com/planning-engine/rust/how-to/reschedule-a-branch.md>).

## Related

- [`Project::solve`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#solve>) - the call that takes these options
- [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/preview-options.md>) - the equivalent options for `preview`
- [`ScheduleResult`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/schedule-result.md>) - the result these options shape
- [Scheduling a Project](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/scheduling-a-project.md#solve-options>) - the options in a solving workflow
- [Reading results](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/reading-results.md#reasons>) - what `reasons` adds to each update
