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


# ProfileQuery

Says what a [`LoadProfile`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/load-profile.md>) covers: a date range, the resources to include, the bucket size and which buckets list their tasks. Build one with `ProfileQuery::new` and set the optional fields afterwards. Pass it to [`Project::load_profile`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#load_profile>) through `.into()`, or to [`Project::preview`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#preview>) as [`PreviewOptions::profile`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/preview-options.md>).

## Declaration

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

`ProfileQuery` has no `Default` implementation, because `from` and `to` are required.

## Constructors

### new

```rust
pub fn new(from: DateTime, to: DateTime) -> ProfileQuery
```

Creates a query for the range `[from, to)` with every other field at its default.

**Parameters**

| Name | Type | Description |
|---|---|---|
| `from` | [`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>) | Start of the range, inclusive |
| `to` | [`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>) | End of the range, exclusive |

**Returns** a `ProfileQuery` with `resources: None`, `basis: None` and `tasks: `[`ProfileTasks::None`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/profile-tasks.md>).

## Fields

| Field | Type | Default | Description |
|---|---|---|---|
| `from` | [`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>) | required | The profile holds every bucket whose start lies in `[from, to)`. |
| `to` | [`DateTime`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/date-time.md>) | required | Must be later than `from`. The range can hold at most 100 000 buckets per resource. |
| `resources` | `Option<Vec<`[`Id`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/id.md>)`>>` | `None` | Resources to include. The profile lists them in the order given here. `None` includes every resource. Each id must name an existing resource. |
| `basis` | `Option<`[`Basis`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/basis.md>)`>` | `None` | Bucket size: one hour or one day. `None` uses the basis derived from [`config.duration_unit`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/scheduling-config.md#duration_unit>) ([`Basis::for_unit`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/data/basis.md#for_unit>)). The profile reports the basis it used in [`LoadProfile::basis`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/load-profile.md>). |
| `tasks` | [`ProfileTasks`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/profile-tasks.md>) | `ProfileTasks::None` | Which buckets list their booked tasks in [`LoadBucket::tasks`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/load-bucket.md>). With `ProfileTasks::None` that field stays `None` in every bucket. |

An invalid query makes the call that takes it fail with [`Error::Input`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/errors/error.md>). See [`Project::load_profile`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/project.md#load_profile>) for the error paths.

## Example

```rust
use plen_core::{
    AssignmentData, Basis, DateTime, ProfileQuery, ProfileTasks, 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 mut task = TaskData::new("a");
    task.start_date = Some(day(5)?);
    task.duration = Some(3.0);

    let data = ProjectData {
        tasks: vec![task],
        resources: vec![ResourceData { id: "dev".into(), capacity: None, calendar_id: None }],
        assignments: vec![AssignmentData {
            id: None,
            task: "a".into(),
            resource: "dev".into(),
            value: 1.0,
            offset: None,
            duration: None,
        }],
        ..Default::default()
    };

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

    let mut query = ProfileQuery::new(day(5)?, day(12)?);
    query.resources = Some(vec!["dev".into()]);
    query.basis = Some(Basis::Day);
    query.tasks = ProfileTasks::All;

    let profile = project.load_profile(&query.into())?;
    for resource in &profile.resources {
        for bucket in &resource.buckets {
            println!("{:?}: {} / {} {:?}", bucket.start, bucket.load, bucket.capacity, bucket.tasks);
        }
    }
    Ok(())
}
```

## Related

- [`LoadProfileOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/load-profile-options.md>) - wraps the query for `Project::load_profile`
- [`PreviewOptions`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/project/preview-options.md>) - carries the query for `Project::preview`
- [`LoadProfile`](<https://docs.dhtmlx.com/planning-engine/rust/api/core/resources/load-profile.md>) - the profile the query produces
- [Resource Load](<https://docs.dhtmlx.com/planning-engine/rust/resources-and-assignment/resource-load.md#querying-a-profile>) - builds and narrows queries
- [Previewing Changes](<https://docs.dhtmlx.com/planning-engine/rust/live-projects/previewing-changes.md#preview-with-load>) - passes a query to a preview
