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


# LevelingScope

Limits a [`Project::level`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#level>) run to part of the plan: the resources whose overallocation gets resolved, the tasks the leveler may move, and the date range in which contention is acted on. Set it as [`LevelingOptions::scope`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/leveling-options.md#scope>). `LevelingScope::default()` sets every field to `None`, which is the same as leveling the whole project.

## Declaration

```rust
#[derive(Clone, Debug, Default)]
pub struct LevelingScope {
    pub resources: Option<Vec<Id>>,
    pub tasks: Option<Vec<Id>>,
    pub from: Option<DateTime>,
    pub to: Option<DateTime>,
}
```

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `resources` | `Option<Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>>` | `None` (all resources) | Resources whose overallocation the run resolves. Overallocation on any other resource is left as it is. Each id must name an existing resource. |
| `tasks` | `Option<Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>>` | `None` (all tasks) | Tasks the leveler may delay or split. Tasks not in the list keep their dates. Each id must name an existing task. |
| `from` | `Option<`[`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>)`>` | `None` (no lower bound) | Start of the range, inclusive. A bucket is in scope when its start lies in `[from, to)`. |
| `to` | `Option<`[`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>)`>` | `None` (no upper bound) | End of the range, exclusive. |

The date range selects which overallocated buckets trigger a correction. It doesn't limit where tasks land or which tasks may move:

- a delayed task can end up after `to`
- a task that starts before `from` can still be delayed when it contends in a bucket inside the range
- a window that straddles `from` or `to` is resolved only for its buckets inside the range

For how overallocation outside the scope is reported, see [`OverallocationWindow::reason`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/overallocation-window.md#reasons>).

See [`Project::level`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#level>) for the errors.

The scope also limits [`LevelingOptions::clear_first`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/leveling-options.md#clear_first>).

## Example

```rust
use plen_core::{
    AssignmentData, DateTime, LevelingOptions, LevelingScope, Project, ProjectData,
    ResourceData, SolveOptions, TaskData,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let day = |d| DateTime::from_ymd_hm(2026, 1, d, 0, 0).ok_or("invalid date");
    let assign = |task: &str| AssignmentData {
        id: None,
        task: task.into(),
        resource: "dev".into(),
        value: 1.0,
        offset: None,
        duration: None,
    };

    let mut a = TaskData::new("a");
    a.start_date = Some(day(5)?);
    a.duration = Some(3.0);
    let mut b = TaskData::new("b");
    b.start_date = Some(day(5)?);
    b.duration = Some(3.0);

    let data = ProjectData {
        tasks: vec![a, b],
        resources: vec![ResourceData { id: "dev".into(), capacity: None, calendar_id: None }],
        assignments: vec![assign("a"), assign("b")],
        ..Default::default()
    };

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

    // Resolve only overallocation of "dev" from Jan 5 on, and only by moving "b".
    let options = LevelingOptions {
        scope: Some(LevelingScope {
            resources: Some(vec!["dev".into()]),
            tasks: Some(vec!["b".into()]),
            from: Some(day(5)?),
            to: None,
        }),
        ..Default::default()
    };

    let result = project.level(&options)?;
    println!("rounds: {}", result.rounds);
    Ok(())
}
```

## Related

- [`LevelingOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/leveling-options.md>) - holds the scope as its `scope` field
- [`Project::level`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#level>) - runs leveling within the scope
- [`OverallocationWindow`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/overallocation-window.md#reasons>) - reports windows outside the scope as `out-of-scope`
- [Leveling Resources](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/leveling-resources.md#leveling-part-of-a-plan>) - levels part of a plan with a scope
