mirror of
https://github.com/herdrdev/herdr.git
synced 2026-10-30 08:06:26 +00:00
113 lines
3.8 KiB
Rust
113 lines
3.8 KiB
Rust
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())
|
|
);
|
|
}
|
|
}
|