1use std::collections::BTreeSet;
4
5pub fn allocate_lowest_slot<I>(occupied_slots: I) -> u32
8where
9 I: IntoIterator<Item = u32>,
10{
11 let set: BTreeSet<u32> = occupied_slots.into_iter().collect();
12 let mut candidate: u32 = 1;
13 while set.contains(&candidate) {
14 candidate = candidate.checked_add(1).expect("slot ID overflow");
15 }
16 candidate
17}
18
19#[cfg(test)]
20mod tests {
21 use super::*;
22
23 #[test]
24 fn test_allocate_empty() {
25 assert_eq!(allocate_lowest_slot(vec![]), 1);
26 }
27
28 #[test]
29 fn test_allocate_contiguous() {
30 assert_eq!(allocate_lowest_slot(vec![1, 2, 3]), 4);
31 }
32
33 #[test]
34 fn test_allocate_gap_recycling() {
35 assert_eq!(allocate_lowest_slot(vec![1, 3, 4]), 2);
36 }
37
38 #[test]
39 fn test_allocate_unsorted_with_duplicates() {
40 assert_eq!(allocate_lowest_slot(vec![3, 1, 1, 2, 5]), 4);
41 }
42}