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


# Reason

What decided a task's date in the last planner run. A `Reason` arrives in [`Mutation::reason`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>), which is filled only when the call ran with `reasons: true` in [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/solve-options.md>) or [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/preview-options.md>).

## Declaration

```rust
#[derive(Clone, Debug, PartialEq)]
pub enum Reason {
    Asap { link_id: Id, source_id: Id },
    Alap { link_id: Id, target_id: Id },
    SummaryTranslation { summary_id: Id },
    Constraint,
    Preferred,
}
```

## Variants

| Variant | Description |
|---|---|
| `Asap { link_id, source_id }` | Forward scheduling. The incoming link `link_id` from the predecessor `source_id` sets the task's start. |
| `Alap { link_id, target_id }` | Backward scheduling ([`schedule_from_end`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/scheduling-config.md>)). The outgoing link `link_id` to the successor `target_id` sets the task's end. |
| `SummaryTranslation { summary_id }` | The task moved together with its summary `summary_id`, which moves as a block. |
| `Constraint` | A constraint set the date: it pulled the task away from the date its links or preferred date would give, or the task has a [`Mso`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/constraint-type.md>) / `Mfo` constraint. |
| `Preferred` | No link or constraint moved the task. It sits at its own preferred date. |

All ids are the ids from the input data ([`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)). When several links give the same date, `Asap` and `Alap` name the first matching one.

## Serialization

With the `serde` feature, `Reason` serializes as an object tagged by `kind`, with kebab-case variant names and camelCase field names:

```json
{ "kind": "asap", "linkId": "l1", "sourceId": "design" }
{ "kind": "summary-translation", "summaryId": "phase-1" }
{ "kind": "preferred" }
```

See [Serialize results to JSON](<https://docs.dhtmlx.com/planning-engine/rust/how-to/serialize-results-to-json.md>).

## Example

```rust
use plen_core::{
    DateTime, LinkData, LinkType, Project, ProjectData, Reason, 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 {
        reasons: true,
        ..Default::default()
    };

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

    for update in &result.updates {
        match &update.reason {
            Some(Reason::Asap { link_id, source_id }) => {
                println!("{} follows {} via link {}", update.id, source_id, link_id)
            }
            Some(Reason::Alap { link_id, target_id }) => {
                println!("{} precedes {} via link {}", update.id, target_id, link_id)
            }
            Some(Reason::SummaryTranslation { summary_id }) => {
                println!("{} moved with summary {}", update.id, summary_id)
            }
            Some(Reason::Constraint) => println!("{} placed by its constraint", update.id),
            Some(Reason::Preferred) => println!("{} kept its preferred date", update.id),
            None => {}
        }
    }
    Ok(())
}
```

## Related

- [`Mutation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) - holds the reason of each updated task
- [`SolveOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/solve-options.md#reasons>) - turns reasons on for `solve`
- [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/preview-options.md>) - turns reasons on for `preview`
- [Reading results](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/reading-results.md#reasons>) - reads reasons from a result
- [Links, constraints and summaries](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/links-constraints-summaries.md>) - shows the links and constraints reasons point to
