Spaces:
Sleeping
Sleeping
File size: 3,254 Bytes
4b94493 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 | use serde::{Deserialize, Serialize};
use solverforge::prelude::*;
use super::RoomKind;
/// A subject meeting that the solver assigns to one timeslot and one room.
#[planning_entity]
#[derive(Serialize, Deserialize)]
pub struct Lesson {
#[planning_id]
pub id: String,
/// Dense solver-facing join key rebuilt by `Plan::rebuild_derived_fields`.
#[serde(skip)]
pub index: usize,
pub subject: String,
pub group_idx: usize,
pub student_count: usize,
pub teacher_idx: Option<usize>,
pub duration: u32,
pub required_room_kind: RoomKind,
// @solverforge:begin entity-variables
/// Scalar planning variable pointing at `Plan.timeslots`.
#[planning_variable(value_range_provider = "timeslots", allows_unassigned = false)]
pub timeslot_idx: Option<usize>,
/// Scalar planning variable pointing at `Plan.rooms`.
#[planning_variable(value_range_provider = "rooms", allows_unassigned = false)]
pub room_idx: Option<usize>,
// @solverforge:end entity-variables
}
impl Lesson {
/// Builds an unassigned lesson with the default lecture-room requirement.
pub fn new(
index: usize,
subject: String,
group_idx: usize,
teacher_idx: Option<usize>,
duration: u32,
) -> Self {
Self::with_required_room_kind(
index,
subject,
group_idx,
teacher_idx,
duration,
RoomKind::Lecture,
)
}
/// Builds an unassigned lesson with an explicit room-kind requirement.
pub fn with_required_room_kind(
index: usize,
subject: String,
group_idx: usize,
teacher_idx: Option<usize>,
duration: u32,
required_room_kind: RoomKind,
) -> Self {
Self::with_details(
index,
subject,
group_idx,
30,
teacher_idx,
duration,
required_room_kind,
)
}
/// Builds an unassigned lesson with every field needed by the data seed.
pub fn with_details(
index: usize,
subject: String,
group_idx: usize,
student_count: usize,
teacher_idx: Option<usize>,
duration: u32,
required_room_kind: RoomKind,
) -> Self {
Self {
id: format!("lesson-{index}"),
index,
subject,
group_idx,
student_count,
teacher_idx,
duration,
required_room_kind,
// @solverforge:begin entity-variable-init
timeslot_idx: None,
room_idx: None,
// @solverforge:end entity-variable-init
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_lesson_construction() {
let entity = Lesson::new(
0,
"test".to_string(),
Default::default(),
None,
Default::default(),
);
assert_eq!(entity.id, "lesson-0");
let _ = &entity.subject;
let _ = &entity.group_idx;
let _ = &entity.student_count;
let _ = &entity.teacher_idx;
let _ = &entity.duration;
let _ = &entity.required_room_kind;
}
}
|