slots#
Turns a Pool of workers and a list of Requirements into the Slots that Project::suggest_assignments takes. Existing active assignments are bound to the slots, so repeated runs stay stable after a commit. Part of the plen-assign crate.
Signature#
Synchronous. Reads the project's accepted state through Project::roster and never modifies the project.
Parameters#
| Name | Type | Description |
|---|---|---|
project |
&Project |
A solved project with no unsolved edits. Tasks, resources and assignments are checked against its accepted state. |
pool |
&Pool |
Workers that may be assigned. Pool order sets the order of each slot's allowed. |
requirements |
&[Requirement] |
What each task needs. An empty slice returns an empty Vec. |
Returns#
Ok(Vec<Slot>): for each requirement, count slots, in requirement order, then instance order. Each slot is filled in as follows:
| Field | Value |
|---|---|
id |
"<requirement id>#<n>", n = 1..=count (for example be#1, be#2) |
task |
The requirement's task |
allowed |
Pool workers for which every SkillMatch of the requirement holds, in pool order. No matches allows every worker. |
value |
The requirement's units |
assignment |
The existing active assignment bound to this slot, or None |
On the next call, an assignment created from a slot binds back to that slot by id; see Requirement for why a requirement id must stay on its task.
The result can be passed to suggest_assignments as is.
Binding#
The task's existing active assignments are bound per task, across all requirements on that task, in three steps:
- Slot id. An assignment whose id is one of the requirement's slot ids binds to that slot, even when its resource isn't in
allowed. The slot is then broken (AssignTarget::Broken). This step runs for every requirement of the task before any explicit list. - Explicit list.
Requirement::assignments:Some(list)replaces automatic binding for that requirement. A listed slot-id assignment keeps its slot, the other entries take the remaining slots in order, and leftover slots stay empty.Some(vec![])leaves every slot empty. - Matching. A deterministic maximum bipartite matching binds the remaining assignments to the empty slots of requirements without a list. An assignment can take a slot only when its resource is in the slot's
allowed. Input order decides between equal matchings, and an earlier requirement can't take the only worker a later one fits.
Assignments left unbound stay on the task without a slot.
Errors#
Returns MatchError. The first failing check wins: the project state, then the pool, then each requirement in input order.
| Error | When it occurs |
|---|---|
MatchError::Project(ProjectError::NoBaseline) |
The project is unsolved or has unsolved edits (after apply). |
MatchError::Invalid |
The pool or a requirement is invalid. path names the item. |
MatchError::Invalid paths:
| Path | When it occurs |
|---|---|
pool.workers[i].resource |
Unknown resource, or the same resource listed as two workers |
pool.workers[i].skills[j].id |
The same skill listed twice on one worker |
pool.workers[i].skills[j].value |
Not finite |
requirements[i].id |
Duplicate requirement id, or one of its slot ids is an active assignment on another task |
requirements[i].task |
Unknown or unscheduled task |
requirements[i].count |
0 |
requirements[i].units |
Not finite or <= 0 |
requirements[i].matches[j].value |
Not finite |
requirements[i].assignments |
More entries than count, or an assignment with one of this requirement's slot ids left out of the list |
requirements[i].assignments[k] |
Unknown or inactive assignment, an assignment on another task, or one bound twice (the message names the other requirement when it already holds it) |
There's no StaleBaseline: the function takes no baseline token.
Example#
use ;
use ;
For the full workflow, see Skills and requirements.
Related#
Project::suggest_assignments- consumes the returned slotsSlot- the type of each returned itemSuggestOptions- options for the call the slots are passed to- Suggesting assignments - shows how the slots are filled and committed
- Error handling - shows how to handle the
MatchErrorthis function returns