rmux-server 0.9.0

Tokio daemon and request dispatcher for the RMUX terminal multiplexer.
Documentation
use rmux_core::{OptionMutationOutcome, PaneId};
use rmux_proto::{OptionScopeSelector, PaneTarget, RmuxError};

pub(super) fn pane_id_for_resolved_target(
    state: &crate::pane_terminals::HandlerState,
    target: &PaneTarget,
) -> Result<rmux_proto::PaneId, RmuxError> {
    state
        .sessions
        .session(target.session_name())
        .and_then(|session| session.window_at(target.window_index()))
        .and_then(|window| window.pane(target.pane_index()))
        .map(|pane| pane.id())
        .ok_or_else(|| {
            RmuxError::invalid_target(target.to_string(), "pane index does not exist in session")
        })
}

pub(super) fn pane_option_events_for_outcome(
    state: &crate::pane_terminals::HandlerState,
    outcome: &OptionMutationOutcome,
) -> Vec<(PaneId, u64, OptionMutationOutcome)> {
    let mut events = Vec::new();
    collect_pane_option_events(state, outcome, &mut events);
    events
}

pub(super) fn synchronize_pane_option_aliases_for_outcome(
    state: &mut crate::pane_terminals::HandlerState,
    outcome: &OptionMutationOutcome,
) -> Result<(), RmuxError> {
    if outcome.changed {
        if let OptionScopeSelector::Pane(target) = &outcome.scope {
            state.synchronize_pane_alias_options_from_target(target)?;
        }
    }
    for related in &outcome.related {
        synchronize_pane_option_aliases_for_outcome(state, related)?;
    }
    Ok(())
}

fn collect_pane_option_events(
    state: &crate::pane_terminals::HandlerState,
    outcome: &OptionMutationOutcome,
    events: &mut Vec<(PaneId, u64, OptionMutationOutcome)>,
) {
    if let Some(event) = pane_option_event_for_option_scope(state, &outcome.scope, outcome) {
        events.push(event);
    }
    for related in &outcome.related {
        collect_pane_option_events(state, related, events);
    }
}

fn pane_option_event_for_option_scope(
    state: &crate::pane_terminals::HandlerState,
    scope: &OptionScopeSelector,
    outcome: &OptionMutationOutcome,
) -> Option<(PaneId, u64, OptionMutationOutcome)> {
    match scope {
        OptionScopeSelector::Pane(target) => pane_option_event_for_target(state, target, outcome),
        OptionScopeSelector::ServerGlobal
        | OptionScopeSelector::SessionGlobal
        | OptionScopeSelector::WindowGlobal
        | OptionScopeSelector::Session(_)
        | OptionScopeSelector::Window(_) => None,
    }
}

fn pane_option_event_for_target(
    state: &crate::pane_terminals::HandlerState,
    target: &PaneTarget,
    outcome: &OptionMutationOutcome,
) -> Option<(PaneId, u64, OptionMutationOutcome)> {
    if !outcome.changed {
        return None;
    }
    let pane_id = pane_id_for_resolved_target(state, target).ok()?;
    let generation = state.pane_output_generation_for_target(target, pane_id);
    Some((pane_id, generation, outcome.clone()))
}