rmux-server 0.1.2

Tokio daemon and request dispatcher for the RMUX terminal multiplexer.
Documentation
use std::cmp::Ordering;

use rmux_core::{BufferView, Session, Window};
use rmux_proto::SessionName;

use super::mode_tree_model::{ClientSnapshot, SortOrder};

pub(super) fn sort_sessions(
    sessions: &mut Vec<(&SessionName, &Session)>,
    sort_order: Option<SortOrder>,
    reversed: bool,
) {
    sessions.sort_by(|(left_name, left), (right_name, right)| {
        let ordering = match sort_order.unwrap_or(SortOrder::Index) {
            SortOrder::Index => left.id().cmp(&right.id()),
            SortOrder::Name => left_name.as_str().cmp(right_name.as_str()),
            SortOrder::Activity => left.active_window_index().cmp(&right.active_window_index()),
            SortOrder::Creation => left.id().cmp(&right.id()),
            SortOrder::Size => left.window().size().cols.cmp(&right.window().size().cols),
        };
        stable_order(ordering, reversed, left_name.as_str(), right_name.as_str())
    });
}

pub(super) fn sort_windows(
    windows: &mut Vec<(&u32, &Window)>,
    sort_order: Option<SortOrder>,
    reversed: bool,
) {
    windows.sort_by(|(left_index, left), (right_index, right)| {
        let ordering = match sort_order.unwrap_or(SortOrder::Index) {
            SortOrder::Index => left_index.cmp(right_index),
            SortOrder::Name => left
                .name()
                .unwrap_or_default()
                .cmp(right.name().unwrap_or_default()),
            SortOrder::Activity => left.active_pane_index().cmp(&right.active_pane_index()),
            SortOrder::Creation => left_index.cmp(right_index),
            SortOrder::Size => left.size().cols.cmp(&right.size().cols),
        };
        stable_order(ordering, reversed, left_index, right_index)
    });
}

pub(super) fn sort_buffer_entries(
    entries: &mut [BufferView<'_>],
    sort_order: Option<SortOrder>,
    reversed: bool,
) {
    entries.sort_by(|left, right| {
        let ordering = match sort_order.unwrap_or(SortOrder::Creation) {
            SortOrder::Creation | SortOrder::Index => left.order().cmp(&right.order()),
            SortOrder::Name => left.name().cmp(right.name()),
            SortOrder::Size => left.size().cmp(&right.size()),
            SortOrder::Activity => left.created().cmp(&right.created()),
        };
        stable_order(ordering, reversed, left.name(), right.name())
    });
}

pub(super) fn sort_clients(
    clients: &mut [ClientSnapshot],
    sort_order: Option<SortOrder>,
    reversed: bool,
) {
    clients.sort_by(|left, right| {
        let ordering = match sort_order.unwrap_or(SortOrder::Name) {
            SortOrder::Name => left.label.cmp(&right.label),
            SortOrder::Size => (left.width, left.height).cmp(&(right.width, right.height)),
            SortOrder::Creation | SortOrder::Index => left.order.cmp(&right.order),
            SortOrder::Activity => right.activity.cmp(&left.activity),
        };
        stable_order(ordering, reversed, &left.label, &right.label)
    });
}

pub(super) fn stable_order<T: Ord>(
    ordering: Ordering,
    reversed: bool,
    left: T,
    right: T,
) -> Ordering {
    let primary = if reversed {
        ordering.reverse()
    } else {
        ordering
    };
    if primary.is_eq() {
        left.cmp(&right)
    } else {
        primary
    }
}

pub(super) fn split_name_value(line: &str) -> (String, String) {
    match line.split_once(' ') {
        Some((name, value)) => (name.to_owned(), value.to_owned()),
        None => (line.to_owned(), String::new()),
    }
}

pub(super) fn sort_order_name(sort_order: SortOrder) -> &'static str {
    match sort_order {
        SortOrder::Index => "index",
        SortOrder::Name => "name",
        SortOrder::Activity => "activity",
        SortOrder::Creation => "creation",
        SortOrder::Size => "size",
    }
}