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


# MutationKind

The kind of task an update entry describes: a regular task, a summary or a milestone. It's the type of the [`Mutation::kind`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) field, and it matches the task's [`TaskType`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-type.md>) in the input data.

## Declaration

```rust
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum MutationKind {
    Task,
    Summary,
    Milestone,
}
```

With the `serde` feature, `MutationKind` implements `Serialize` and `Deserialize`. Variants are written in kebab-case: `"task"`, `"summary"`, `"milestone"`.

## Variants

| Variant | Serialized | Description |
|---|---|---|
| `Task` | `"task"` | The entry belongs to a regular task ([`TaskType::Task`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-type.md>)). |
| `Summary` | `"summary"` | The entry belongs to a summary task (`TaskType::Summary`). |
| `Milestone` | `"milestone"` | The entry belongs to a milestone (`TaskType::Milestone`). |

For how an entry is fed back into the project, see [`Mutation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>).

## Example

Schedule a summary with one task and a closing milestone, then group the update entries by kind:

```rust
use plen_core::{
    schedule, DateTime, MutationKind, ProjectData, SolveOptions, TaskData, TaskType,
};

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

    let data = ProjectData {
        tasks: vec![
            TaskData { task_type: TaskType::Summary, ..TaskData::new("phase") },
            TaskData {
                parent: Some("phase".into()),
                start_date: Some(start),
                duration: Some(3.0),
                ..TaskData::new("build")
            },
            TaskData {
                parent: Some("phase".into()),
                task_type: TaskType::Milestone,
                start_date: Some(start),
                duration: Some(0.0),
                ..TaskData::new("release")
            },
        ],
        ..Default::default()
    };

    let options = SolveOptions { include_unchanged: true, ..Default::default() };
    let result = schedule(data, &options)?;

    for update in &result.updates {
        let label = match update.kind {
            MutationKind::Task => "task",
            MutationKind::Summary => "summary",
            MutationKind::Milestone => "milestone",
        };
        println!("{:?} ({label}): {:?} -> {:?}", update.id, update.start_date, update.end_date);
    }
    Ok(())
}
```

## Related

- [`Mutation`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/results/mutation.md>) - holds the kind as its `kind` field
- [`TaskType`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/task-type.md>) - the input type the kind mirrors
- [Reading results](<https://docs.dhtmlx.com/planning-engine/rust/scheduling/reading-results.md#updates>) - reads update entries from a result
