///|
/// Copy an array while preserving order.
pub fn[T] copy_array(values : Array[T]) -> Array[T] {
let result : Array[T] = []
for value in values {
result.push(value)
}
result
}
///|
/// Whether a string occurs in an array.
pub fn string_array_contains(values : Array[String], target : String) -> Bool {
for value in values {
if value == target {
return true
}
}
false
}
///|
/// Insert a string only when it is not already present.
pub fn push_unique_string(values : Array[String], value : String) -> Unit {
if !string_array_contains(values, value) {
values.push(value)
}
}
///|
/// Count exact string matches.
pub fn count_string(values : Array[String], target : String) -> Int {
let mut count = 0
for value in values {
if value == target {
count = count + 1
}
}
count
}
///|
/// Return the smaller integer.
pub fn min_int(left : Int, right : Int) -> Int {
if left < right {
left
} else {
right
}
}
///|
/// Return the larger integer.
pub fn max_int(left : Int, right : Int) -> Int {
if left > right {
left
} else {
right
}
}
///|
/// Integer absolute value without relying on target-specific helpers.
pub fn abs_int(value : Int) -> Int {
if value < 0 {
-value
} else {
value
}
}
///|
/// Clamp an integer to an inclusive range.
pub fn clamp_int(value : Int, lower : Int, upper : Int) -> Int {
if value < lower {
lower
} else if value > upper {
upper
} else {
value
}
}
///|
/// Find a worker by identifier.
pub fn find_worker(workers : Array[Worker], id : String) -> Worker? {
for worker in workers {
if worker.id == id {
return Some(worker)
}
}
None
}
///|
/// Find a visit by identifier.
pub fn find_visit(visits : Array[Visit], id : String) -> Visit? {
for visit in visits {
if visit.id == id {
return Some(visit)
}
}
None
}
///|
/// Find an assignment for a visit.
pub fn find_assignment(
assignments : Array[Assignment],
visit_id : String,
) -> Assignment? {
for assignment in assignments {
if assignment.visit_id == visit_id {
return Some(assignment)
}
}
None
}
///|
/// Select all assignments belonging to a worker.
pub fn assignments_for_worker(
assignments : Array[Assignment],
worker_id : String,
) -> Array[Assignment] {
let result : Array[Assignment] = []
for assignment in assignments {
if assignment.worker_id == worker_id {
result.push(assignment)
}
}
result
}
///|
/// Total assigned service time for a worker.
pub fn assigned_minutes(
assignments : Array[Assignment],
worker_id : String,
) -> Int {
let mut total = 0
for assignment in assignments {
if assignment.worker_id == worker_id {
total = total + assignment.end_minute - assignment.start_minute
}
}
total
}
///|
/// Count diagnostics at one severity.
pub fn count_diagnostics(
diagnostics : Array[Diagnostic],
level : DiagnosticLevel,
) -> Int {
let mut count = 0
for diagnostic in diagnostics {
if diagnostic.level == level {
count = count + 1
}
}
count
}
///|
/// True when any diagnostic blocks scheduling.
pub fn diagnostics_have_errors(diagnostics : Array[Diagnostic]) -> Bool {
count_diagnostics(diagnostics, Error) > 0
}