use crate::api::schema::{ResponseResult, SessionSnapshot}; use crate::app::App; use super::responses::encode_success; impl App { pub(super) fn handle_session_snapshot(&mut self, id: String) -> String { encode_success( id, ResponseResult::SessionSnapshot { snapshot: Box::new(self.session_snapshot()), }, ) } fn session_snapshot(&self) -> SessionSnapshot { let focused_workspace_id = self .state .active .map(|ws_idx| self.public_workspace_id(ws_idx)); let focused_tab_id = self.state.active.and_then(|ws_idx| { let ws = self.state.workspaces.get(ws_idx)?; self.public_tab_id(ws_idx, ws.active_tab) }); let focused_pane_id = self.state.active.and_then(|ws_idx| { let ws = self.state.workspaces.get(ws_idx)?; self.public_pane_id(ws_idx, ws.focused_pane_id()?) }); let mut workspaces = Vec::new(); let mut tabs = Vec::new(); let mut layouts = Vec::new(); for (ws_idx, ws) in self.state.workspaces.iter().enumerate() { workspaces.push(self.workspace_info(ws_idx)); for tab_idx in 0..ws.tabs.len() { if let Some(tab) = self.tab_info(ws_idx, tab_idx) { tabs.push(tab); } if let Some(layout) = self.pane_layout_snapshot(ws_idx, tab_idx) { layouts.push(layout); } } } SessionSnapshot { version: crate::build_info::version(), protocol: crate::protocol::PROTOCOL_VERSION, focused_workspace_id, focused_tab_id, focused_pane_id, workspaces, tabs, panes: self.collect_panes_for_workspace(None).unwrap_or_default(), layouts, agents: self.collect_agent_infos(), } } } #[cfg(test)] mod tests { use crate::api::schema::{EmptyParams, Method, ResponseResult, SuccessResponse}; use crate::{config::Config, workspace::Workspace}; fn app_with_two_tabs() -> crate::app::App { let (_api_tx, api_rx) = tokio::sync::mpsc::unbounded_channel(); let mut app = crate::app::App::new( &Config::default(), true, None, api_rx, crate::api::EventHub::default(), ); let mut workspace = Workspace::test_new("snapshot"); workspace.test_add_tab(None); app.state.workspaces = vec![workspace]; app.state.ensure_test_terminals(); app.state.active = Some(0); app } #[test] fn session_snapshot_bootstraps_runtime_resources() { let mut app = app_with_two_tabs(); let response = app.handle_api_request(crate::api::schema::Request { id: "req_snapshot".into(), method: Method::SessionSnapshot(EmptyParams::default()), }); let success: SuccessResponse = serde_json::from_str(&response).unwrap(); let ResponseResult::SessionSnapshot { snapshot } = success.result else { panic!("expected session snapshot response"); }; assert_eq!(success.id, "req_snapshot"); assert_eq!(snapshot.workspaces.len(), 1); assert_eq!(snapshot.tabs.len(), 2); assert_eq!(snapshot.panes.len(), 2); assert_eq!(snapshot.layouts.len(), 2); assert_eq!( snapshot.focused_workspace_id.as_deref(), Some(snapshot.workspaces[0].workspace_id.as_str()) ); assert_eq!( snapshot.focused_tab_id.as_deref(), Some(snapshot.tabs[0].tab_id.as_str()) ); assert_eq!( snapshot.focused_pane_id.as_deref(), Some(snapshot.panes[0].pane_id.as_str()) ); } }