Agents for developpement added + frontend add + backend added. Git viewer created + agent and template creator + layout and project creator
74 lines
2.3 KiB
Rust
74 lines
2.3 KiB
Rust
//! Window/tab use cases (ARCHITECTURE §6, §10; L10).
|
|
//!
|
|
//! [`MoveTabToNewWindow`] detaches a tab into a new OS window. The topology
|
|
//! change is the pure [`Workspace::move_tab_to_new_window`] domain operation; the
|
|
//! use case only loads/persists the workspace and mints the new window id.
|
|
|
|
use std::sync::Arc;
|
|
|
|
use domain::ids::{TabId, WindowId};
|
|
use domain::layout::Workspace;
|
|
use domain::ports::{IdGenerator, ProjectStore};
|
|
|
|
use crate::error::AppError;
|
|
|
|
/// Input for [`MoveTabToNewWindow::execute`].
|
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
|
pub struct MoveTabToNewWindowInput {
|
|
/// The tab to detach into its own new window.
|
|
pub tab_id: TabId,
|
|
}
|
|
|
|
/// Output of [`MoveTabToNewWindow::execute`].
|
|
#[derive(Debug, Clone, PartialEq)]
|
|
pub struct MoveTabToNewWindowOutput {
|
|
/// The id minted for the new window.
|
|
pub new_window_id: WindowId,
|
|
/// The resulting workspace (already persisted).
|
|
pub workspace: Workspace,
|
|
}
|
|
|
|
/// Detaches a tab into a freshly-created window and persists the workspace.
|
|
pub struct MoveTabToNewWindow {
|
|
store: Arc<dyn ProjectStore>,
|
|
ids: Arc<dyn IdGenerator>,
|
|
}
|
|
|
|
impl MoveTabToNewWindow {
|
|
/// Builds the use case from its ports.
|
|
#[must_use]
|
|
pub fn new(store: Arc<dyn ProjectStore>, ids: Arc<dyn IdGenerator>) -> Self {
|
|
Self { store, ids }
|
|
}
|
|
|
|
/// Executes the detach.
|
|
///
|
|
/// # Errors
|
|
/// - [`AppError::NotFound`] if the tab is not in the workspace,
|
|
/// - [`AppError::Invalid`] if the resulting window is invalid,
|
|
/// - [`AppError::Store`] on persistence failure.
|
|
pub async fn execute(
|
|
&self,
|
|
input: MoveTabToNewWindowInput,
|
|
) -> Result<MoveTabToNewWindowOutput, AppError> {
|
|
let workspace = self.store.load_workspace().await?;
|
|
let new_window_id = WindowId::from_uuid(self.ids.new_uuid());
|
|
|
|
let workspace = workspace
|
|
.move_tab_to_new_window(input.tab_id, new_window_id)
|
|
.map_err(|e| match e {
|
|
domain::layout::LayoutError::TabNotFound(t) => {
|
|
AppError::NotFound(format!("tab {t}"))
|
|
}
|
|
other => AppError::Invalid(other.to_string()),
|
|
})?;
|
|
|
|
self.store.save_workspace(&workspace).await?;
|
|
|
|
Ok(MoveTabToNewWindowOutput {
|
|
new_window_id,
|
|
workspace,
|
|
})
|
|
}
|
|
}
|