concord 1.1.0

A terminal user interface client for Discord
Documentation
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);
    }
}