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


# Slot

One requirement instance on one task: the task, the resources eligible for it, and the assignment that fills it, if any. Create one with [`Slot::new`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/suggest/slot.md#new>), or get a list from [`plen_assign::slots`](<https://docs.dhtmlx.com/planning-engine/rust/api/assign/slots.md>). Slots are the input of [`Project::suggest_assignments`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#suggest_assignments>). A slot lists eligible resources only, never skills.

## Declaration

```rust
#[derive(Clone, Debug, PartialEq)]
pub struct Slot {
    pub id: Id,
    pub task: Id,
    pub allowed: Vec<Id>,
    pub value: f64,
    pub assignment: Option<Id>,
}
```

`Slot` doesn't implement `Default`. Start from `Slot::new` and set other fields with struct update syntax.

## Constructors

### new

```rust
pub fn new(id: impl Into<Id>, task: impl Into<Id>, allowed: Vec<Id>) -> Slot
```

Creates an empty slot with `value: 1.0` and `assignment: None`.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `id` | `impl Into<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | Slot id |
| `task` | `impl Into<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | Task the slot belongs to |
| `allowed` | `Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | Eligible resources, in preference order |

**Returns** the new `Slot`.

## Fields

| Field | Type | Default via `new` | Description |
|---|---|---|---|
| `id` | [`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>) | - | Unique among the slots of one call. A new assignment that fills the slot gets this id. Echoed in [`SuggestStep::slot`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/suggest/suggest-step.md>) and in the `unfilled` and `invalid` lists of [`SuggestResult`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/suggest/suggest-result.md>). |
| `task` | [`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>) | - | A scheduled leaf task. |
| `allowed` | `Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | - | Eligible resources. The order is the tie-break preference. A duplicate entry counts once. |
| `value` | `f64` | `1.0` | Units of a new assignment that fills the slot (1 = 100 %). Must be finite and `> 0`. |
| `assignment` | `Option<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>` | `None` | The active assignment that fills the slot. `None` = the slot is empty. |

Whether the slot is empty, held by a resource outside `allowed`, or held by a resource in `allowed` decides its [`AssignTarget`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/suggest/assign-target.md>) category.

A filled slot's new assignment takes the slot id. To keep that binding on the next run, set `assignment: Some(slot_id)`.

## Accepted values

[`Project::suggest_assignments`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#suggest_assignments>) checks the slots in input order and returns [`Error::Input`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/errors/error.md>) with one of these paths:

| Path | When |
|---|---|
| `slots[i].id` | The id repeats another slot's id, or equals an existing assignment id (active or inactive) other than this slot's own `assignment` |
| `slots[i].task` | The task is unknown, unscheduled or a summary |
| `slots[i].allowed[j]` | The resource is unknown |
| `slots[i].value` | `value` isn't finite or is `<= 0` |
| `slots[i].assignment` | The assignment is unknown, inactive, on another task, or bound by two slots |

## Serialization

With the `serde` feature (`cargo add plen-core --features serde`), `Slot` implements `Serialize` only. `assignment` is omitted when it's `None`.

## Example

One empty slot on task `1` at half-time that prefers `dev2`, and one slot already filled by the assignment `review`.

```rust
use plen_core::{
    AssignmentData, DateTime, Project, ProjectData, ProjectOptions, ResourceData, Slot,
    SolveOptions, SuggestOptions, 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 data = ProjectData {
        tasks: vec![
            TaskData { start_date: Some(monday), duration: Some(2.0), ..TaskData::new(1) },
            TaskData { start_date: Some(monday), duration: Some(3.0), ..TaskData::new(2) },
        ],
        resources: ["dev1", "dev2"]
            .iter()
            .map(|id| ResourceData { id: (*id).into(), capacity: None, calendar_id: None })
            .collect(),
        assignments: vec![AssignmentData {
            id: Some("review".into()),
            task: 2.into(),
            resource: "dev1".into(),
            value: 1.0,
            offset: None,
            duration: None,
        }],
        ..Default::default()
    };

    let mut project = Project::new(ProjectOptions::default());
    project.solve(Some(data), &SolveOptions::default())?;

    let slots = vec![
        Slot { value: 0.5, ..Slot::new("build", 1, vec!["dev2".into(), "dev1".into()]) },
        Slot {
            assignment: Some("review".into()),
            ..Slot::new("review", 2, vec!["dev1".into(), "dev2".into()])
        },
    ];

    let result = project.suggest_assignments(&slots, &SuggestOptions::default())?;
    for step in &result.steps {
        println!("{} -> {}", step.slot, step.to_resource);
    }
    Ok(())
}
```

For how slots are visited, filled and rebalanced, see [Suggesting assignments](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/suggesting-assignments.md>).

## Related

- [`plen_assign::slots`](<https://docs.dhtmlx.com/planning-engine/rust/api/assign/slots.md>) - builds slots from skills and requirements
- [`SuggestOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/suggest/suggest-options.md>) - options passed with the slots to `suggest_assignments`
- [`SuggestResult`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/suggest/suggest-result.md>) - the proposal returned for a list of slots
- [Suggesting assignments](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/suggesting-assignments.md>) - shows building slots and passing them to `suggest_assignments`
- [Skills and Requirements](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/skills-and-requirements.md>) - shows generating slots from a worker pool and requirements
