ProfileQuery#

Says what a LoadProfile 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 through .into(), or to Project::preview as PreviewOptions::profile.

Declaration#

#[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#

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 Start of the range, inclusive
to DateTime End of the range, exclusive

Returns a ProfileQuery with resources: None, basis: None and tasks: ProfileTasks::None.

Fields#

Field Type Default Description
from DateTime required The profile holds every bucket whose start lies in [from, to).
to DateTime required Must be later than from. The range can hold at most 100 000 buckets per resource.
resources Option<Vec<Id>> 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> None Bucket size: one hour or one day. None uses the basis derived from config.duration_unit (Basis::for_unit). The profile reports the basis it used in LoadProfile::basis.
tasks ProfileTasks ProfileTasks::None Which buckets list their booked tasks in LoadBucket::tasks. With ProfileTasks::None that field stays None in every bucket.

An invalid query makes the call that takes it fail with Error::Input. See Project::load_profile for the error paths.

Example#

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(())
}