Skip to main content

patterns/
queue.rs

1use crate::arith::{mul, raise_by};
2use crate::clamp::clamp_upper;
3use crate::seq::{with, Keyed};
4use patterns_macros::because;
5
6pub fn dequeued<T: Clone>(items: &[T]) -> Option<(T, Vec<T>)> {
7    items
8        .split_first()
9        .map(|(head, rest)| (head.clone(), rest.to_vec()))
10}
11because!(dequeued, "taking the front of a queue and the remainder together, so a caller never indexes zero and the empty queue is a value rather than a panic");
12
13pub fn rotated<T: Clone>(items: &[T]) -> Vec<T> {
14    match items.split_first() {
15        Some((head, rest)) => with(rest, head.clone()),
16        None => Vec::new(),
17    }
18}
19because!(rotated, "one turn of a round robin, so a rota or a fair share of bays advances without a caller tracking an index that must wrap");
20
21pub fn moved<T: Keyed + Clone>(from: &[T], to: &[T], key: T::Key) -> (Vec<T>, Vec<T>) {
22    let mut left = Vec::new();
23    let mut arrived = to.to_vec();
24    for item in from {
25        if item.key() == key {
26            arrived.push(item.clone());
27        } else {
28            left.push(item.clone());
29        }
30    }
31    (left, arrived)
32}
33because!(moved, "a transfer between two shelves as one step, so the element cannot be dropped from one without arriving on the other, which without and with as separate calls allow; every element under the key moves, so two sharing a key arrive together rather than one being stranded");
34
35pub fn replaced<T: Keyed + Clone>(items: &[T], item: T) -> Vec<T> {
36    let mut out = Vec::new();
37    for held in items {
38        if held.key() == item.key() {
39            out.push(item.clone());
40        } else {
41            out.push(held.clone());
42        }
43    }
44    out
45}
46because!(replaced, "an update in place that keeps the position, because with after without sends a queued element to the back and silently changes its turn; every element under the key is replaced, so two sharing a key both become the new element and a duplicate is not silently kept");
47
48pub fn page<T: Clone>(items: &[T], size: usize, number: usize) -> Vec<T> {
49    let start = clamp_upper(mul(size, number), items.len());
50    let end = clamp_upper(raise_by(start, size), items.len());
51    items[start..end].to_vec()
52}
53because!(page, "one page of a listing, with the arithmetic that ends a list saturated and clamped here so a request past the end is an empty page rather than a panic");