use std::num::NonZeroU64;
use embers_core::{MuxError, Result};
use embers_protocol::SessionRecord;
use crate::CliConnection;
impl CliConnection {
pub(crate) async fn target_client(&mut self, explicit: Option<u64>) -> Result<NonZeroU64> {
if let Some(client_id) = explicit {
return NonZeroU64::new(client_id)
.ok_or_else(|| MuxError::invalid_input("client id must be non-zero"));
}
if let Some(client_id) = self.default_client {
return Ok(client_id);
}
let clients = self.list_clients().await?;
if let Some(client_id) = self
.caller_client
.filter(|client_id| clients.iter().any(|client| client.id == client_id.get()))
{
return Ok(client_id);
}
let attached = clients
.iter()
.filter(|client| client.current_session_id.is_some())
.collect::<Vec<_>>();
if let Some(session_id) = self
.pane_location()
.await?
.and_then(|location| location.session_id())
&& let Some(client) = attached
.iter()
.filter(|client| client.current_session_id == Some(session_id))
.max_by_key(|client| client.id)
{
return client_id(client.id);
}
match attached.as_slice() {
[client] => client_id(client.id),
[] => Err(MuxError::not_found("no client is attached")),
_ => Err(MuxError::invalid_input(
"several clients are attached; choose one with -c (see list-clients)",
)),
}
}
pub(crate) async fn neighbour_session(
&mut self,
client_id: NonZeroU64,
forward: bool,
) -> Result<SessionRecord> {
let current = self.client_record(client_id).await?.current_session_id;
let mut sessions = self.list_sessions().await?;
sessions.sort_by(|left, right| left.name.cmp(&right.name).then(left.id.cmp(&right.id)));
let count = sessions.len();
if count == 0 {
return Err(MuxError::not_found("no sessions exist"));
}
let position =
current.and_then(|current| sessions.iter().position(|session| session.id == current));
let index = match (position, forward) {
(Some(position), true) => (position + 1) % count,
(Some(position), false) => (position + count - 1) % count,
(None, true) => 0,
(None, false) => count - 1,
};
Ok(sessions.swap_remove(index))
}
}
fn client_id(id: u64) -> Result<NonZeroU64> {
NonZeroU64::new(id).ok_or_else(|| MuxError::protocol("server reported client id 0"))
}