use serde::{Deserialize, Serialize};
use crate::types::{PaneId, SessionId, SessionName, TerminalSizeSpec, WindowId};
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct SessionInfo {
pub id: SessionId,
pub name: SessionName,
#[serde(default)]
pub working_directory: Option<String>,
#[serde(default)]
pub size: TerminalSizeSpec,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub generation: u64,
#[serde(default)]
pub revision: u64,
#[serde(default)]
pub attached_clients: u32,
}
impl SessionInfo {
#[must_use]
pub fn new(id: SessionId, name: SessionName) -> Self {
Self {
id,
name,
working_directory: None,
size: TerminalSizeSpec::default(),
tags: Vec::new(),
generation: 0,
revision: 0,
attached_clients: 0,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct WindowInfo {
pub id: WindowId,
pub session_id: SessionId,
#[serde(default)]
pub index: u32,
#[serde(default)]
pub name: Option<String>,
#[serde(default)]
pub size: TerminalSizeSpec,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub generation: u64,
#[serde(default)]
pub revision: u64,
}
impl WindowInfo {
#[must_use]
pub fn new(id: WindowId, session_id: SessionId) -> Self {
Self {
id,
session_id,
index: 0,
name: None,
size: TerminalSizeSpec::default(),
tags: Vec::new(),
generation: 0,
revision: 0,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PaneInfo {
pub id: PaneId,
pub window_id: WindowId,
pub session_id: SessionId,
#[serde(default)]
pub index: u32,
#[serde(default)]
pub command: Option<Vec<String>>,
#[serde(default)]
pub working_directory: Option<String>,
#[serde(default)]
pub tags: Vec<String>,
#[serde(default)]
pub size: TerminalSizeSpec,
#[serde(default)]
pub process: PaneProcessState,
#[serde(default)]
pub generation: u64,
#[serde(default)]
pub revision: u64,
#[serde(default)]
pub output_sequence: u64,
#[serde(default)]
pub exit_state: Option<PaneExitState>,
}
impl PaneInfo {
#[must_use]
pub fn new(id: PaneId, window_id: WindowId, session_id: SessionId) -> Self {
Self {
id,
window_id,
session_id,
index: 0,
command: None,
working_directory: None,
tags: Vec::new(),
size: TerminalSizeSpec::default(),
process: PaneProcessState::default(),
generation: 0,
revision: 0,
output_sequence: 0,
exit_state: None,
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
#[serde(rename_all = "kebab-case")]
#[non_exhaustive]
pub enum PaneProcessState {
#[default]
Unknown,
Running {
#[serde(default)]
pid: Option<u32>,
},
Exited,
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct PaneExitState {
#[serde(default)]
pub code: Option<i32>,
#[serde(default)]
pub signal: Option<i32>,
#[serde(default)]
pub message: Option<String>,
}
impl PaneExitState {
#[must_use]
pub fn from_code(code: i32) -> Self {
Self {
code: Some(code),
signal: None,
message: None,
}
}
#[must_use]
pub fn from_signal(signal: i32) -> Self {
Self {
code: None,
signal: Some(signal),
message: None,
}
}
}
#[derive(Debug, Default, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
pub struct InfoSnapshot {
#[serde(default)]
pub sessions: Vec<SessionInfo>,
#[serde(default)]
pub windows: Vec<WindowInfo>,
#[serde(default)]
pub panes: Vec<PaneInfo>,
}
impl InfoSnapshot {
#[must_use]
pub fn new(sessions: Vec<SessionInfo>, windows: Vec<WindowInfo>, panes: Vec<PaneInfo>) -> Self {
Self {
sessions,
windows,
panes,
}
}
#[must_use]
pub fn session(&self, session_id: SessionId) -> Option<&SessionInfo> {
self.sessions.iter().find(|info| info.id == session_id)
}
#[must_use]
pub fn window(&self, window_id: WindowId) -> Option<&WindowInfo> {
self.windows.iter().find(|info| info.id == window_id)
}
#[must_use]
pub fn pane(&self, pane_id: PaneId) -> Option<&PaneInfo> {
self.panes.iter().find(|info| info.id == pane_id)
}
}