pub(super) const MAX_EMOJI_REACTION_VISIBLE_ITEMS: usize = 10;
pub(super) fn visible_range_for_selected_span(
total_len: usize,
selected_start: usize,
selected_end: usize,
visible_len: usize,
) -> std::ops::Range<usize> {
let visible_len = visible_len.max(1).min(total_len.max(1));
if total_len <= visible_len {
return 0..total_len;
}
let selected_start = selected_start.min(total_len.saturating_sub(1));
let selected_end = selected_end
.max(selected_start.saturating_add(1))
.min(total_len);
let start = if selected_end.saturating_sub(selected_start) >= visible_len {
selected_start
} else {
selected_end.saturating_sub(visible_len)
}
.min(total_len.saturating_sub(visible_len));
start..start + visible_len
}
pub(super) fn visible_item_range(
items_len: usize,
selected: usize,
visible_items: usize,
) -> std::ops::Range<usize> {
visible_range_for_selected_span(
items_len,
selected,
selected.saturating_add(1),
visible_items,
)
}
#[cfg(test)]
mod tests {
use super::{visible_item_range, visible_range_for_selected_span};
#[test]
fn visible_item_range_keeps_selected_item_visible() {
assert_eq!(visible_item_range(6, 5, 3), 3..6);
assert_eq!(visible_item_range(6, 0, 3), 0..3);
}
#[test]
fn visible_range_for_selected_span_keeps_selected_block_visible() {
assert_eq!(visible_range_for_selected_span(12, 8, 10, 4), 6..10);
assert_eq!(visible_range_for_selected_span(12, 8, 12, 3), 8..11);
}
}