From 767315a65e0039ac5cac56d48ff1ad40e75c354d Mon Sep 17 00:00:00 2001 From: mow Date: Mon, 9 Mar 2026 21:06:51 +0100 Subject: [PATCH] refactor(examples/cli): update to new SessionCommand API --- core/examples/cli.rs | 283 +++++++++++++++++++++++++++---------------- 1 file changed, 178 insertions(+), 105 deletions(-) diff --git a/core/examples/cli.rs b/core/examples/cli.rs index cf4304e..7d4edb3 100644 --- a/core/examples/cli.rs +++ b/core/examples/cli.rs @@ -6,10 +6,10 @@ use clap::{ArgGroup, Parser}; use noctua_core::document::manager::{DocumentManager, DocumentState}; use noctua_core::document::session::command::SessionCommand; -use noctua_core::document::session::data::CollectionKind; +use noctua_core::document::session::data::{CollectionKind, SessionData}; use std::path::PathBuf; -// ── ANSI helpers ── +// ANSI helpers const RESET: &str = "\x1b[0m"; const BOLD: &str = "\x1b[1m"; @@ -40,36 +40,32 @@ fn info(text: &str) { println!(" {YELLOW}i{RESET} {text}"); } -fn print_session(manager: &DocumentManager, session_name: &str) { - if let Some(session) = manager.session(session_name) { - let kind_label = match session.kind { - CollectionKind::DirectoryBrowser => "DirectoryBrowser", - CollectionKind::DocumentCollection => "DocumentCollection", +fn print_session(session: &SessionData, active_doc_index: Option) { + let kind_label = match session.kind { + CollectionKind::DirectoryBrowser => "DirectoryBrowser", + CollectionKind::DocumentCollection => "DocumentCollection", + }; + println!( + " {MAGENTA}Session: {BOLD}{}{RESET} {DIM}({kind_label}, {} items, active: {:?}){RESET}", + session.name, + session.items.len(), + active_doc_index, + ); + for (i, item) in session.items.iter().enumerate() { + let marker = if active_doc_index == Some(i) { + format!("{GREEN}=>{RESET}") + } else { + format!("{DIM} {RESET}") }; + let name = item + .path + .file_name() + .and_then(|n| n.to_str()) + .unwrap_or("?"); println!( - " {MAGENTA}Collection: {BOLD}{}{RESET} {DIM}({kind_label}, {} items, index: {:?}){RESET}", - session.name, - session.items.len(), - session.current_index + " {marker} {DIM}[{i}]{RESET} {name} {DIM}(page {}){RESET}", + item.page_index ); - for (i, item) in session.items.iter().enumerate() { - let marker = if session.current_index == Some(i) { - format!("{GREEN}=>{RESET}") - } else { - format!("{DIM} {RESET}") - }; - let name = item - .path - .file_name() - .and_then(|n| n.to_str()) - .unwrap_or("?"); - println!( - " {marker} {DIM}[{i}]{RESET} {name} {DIM}(page {}){RESET}", - item.page_index - ); - } - } else { - err(&format!("Session '{session_name}' not found")); } } @@ -82,9 +78,11 @@ fn exec(manager: &mut DocumentManager, label: &str, command: SessionCommand) { } } -fn print_nav_index(manager: &DocumentManager, label: &str) { - if let Some(session) = manager.active_session() { - ok(&format!("{label:<28} → index {:?}", session.current_index)); +fn print_active_session(mgr: &DocumentManager) { + if let Some(session) = mgr.active_session() { + print_session(session, mgr.active_document_index()); + } else { + info("No active session"); } } @@ -98,7 +96,6 @@ fn print_nav_index(manager: &DocumentManager, label: &str) { .args(["open_document", "open_directory", "open_session"]) ) )] - struct Opt { /// Open a document (raster, vector, portable) #[arg(long, value_name = "PATH")] @@ -119,12 +116,16 @@ fn main() { let cli = Opt::parse(); let mut mgr = DocumentManager::new(); - // ── Open source ── + // Open source heading("Opening source"); if let Some(path) = cli.open_session { - exec(&mut mgr, "Open session file", SessionCommand::Open { path }); + exec( + &mut mgr, + "Open session file", + SessionCommand::OpenSession { path }, + ); } else if let Some(path) = cli.open_document { let dir = path .parent() @@ -139,28 +140,27 @@ fn main() { exec( &mut mgr, - &format!("New browser session '{session_name}'"), - SessionCommand::New { + &format!("New session '{session_name}'"), + SessionCommand::NewSession { name: session_name.clone(), - kind: CollectionKind::DirectoryBrowser, }, ); exec( &mut mgr, &format!("Select '{session_name}'"), - SessionCommand::Select { + SessionCommand::SelectSession { name: session_name.clone(), }, ); exec( &mut mgr, &format!("Add directory {}", dir.display()), - SessionCommand::AddDirectory { dir }, + SessionCommand::AddDirectoryToSession { dir }, ); exec( &mut mgr, &format!("Add document {}", path.display()), - SessionCommand::AddDocument { path }, + SessionCommand::AddDocumentToSession { path }, ); } else if let Some(path) = cli.open_directory { let session_name = path @@ -172,26 +172,25 @@ fn main() { exec( &mut mgr, &format!("New session '{session_name}'"), - SessionCommand::New { + SessionCommand::NewSession { name: session_name.clone(), - kind: CollectionKind::DirectoryBrowser, }, ); exec( &mut mgr, &format!("Select '{session_name}'"), - SessionCommand::Select { + SessionCommand::SelectSession { name: session_name.clone(), }, ); exec( &mut mgr, &format!("Add directory {}", path.display()), - SessionCommand::AddDirectory { dir: path }, + SessionCommand::AddDirectoryToSession { dir: path }, ); } - // ── State summary ── + // State summary heading("State after open"); @@ -202,7 +201,7 @@ fn main() { DocumentState::Loaded(_) => ok("Document loaded"), } - let active_name = match mgr.active_session_name.clone() { + let active_name = match mgr.active_session().map(|s| s.name.clone()) { Some(n) => n, None => { info("No active session – nothing more to test."); @@ -210,115 +209,189 @@ fn main() { } }; - print_session(&mgr, &active_name); + print_active_session(&mgr); - // ── Navigation ── + // Navigation heading("Navigation"); exec(&mut mgr, "NextDocument", SessionCommand::NextDocument); - print_nav_index(&mgr, "After NextDocument"); + ok(&format!( + "After NextDocument → index {:?}", + mgr.active_document_index() + )); exec( &mut mgr, "PreviousDocument", SessionCommand::PreviousDocument, ); - print_nav_index(&mgr, "After PreviousDocument"); + ok(&format!( + "After PreviousDocument → index {:?}", + mgr.active_document_index() + )); exec( &mut mgr, "SelectDocument { index: 0 }", SessionCommand::SelectDocument { index: 0 }, ); - print_nav_index(&mgr, "After SelectDocument(0)"); + ok(&format!( + "After SelectDocument(0) → index {:?}", + mgr.active_document_index() + )); - // ── Collection operations ── + // Move operations - heading("Collection operations"); + heading("Move operations"); + + step("Before MoveDocumentDown:"); + print_active_session(&mgr); + + exec( + &mut mgr, + "MoveDocumentDown", + SessionCommand::MoveDocumentDown, + ); + ok(&format!( + "After MoveDocumentDown → index {:?}", + mgr.active_document_index() + )); + + exec(&mut mgr, "MoveDocumentUp", SessionCommand::MoveDocumentUp); + ok(&format!( + "After MoveDocumentUp → index {:?}", + mgr.active_document_index() + )); + + // Copy / Paste + + heading("Copy / Paste"); exec( &mut mgr, "New session 'Favorites'", - SessionCommand::New { + SessionCommand::NewSession { name: "Favorites".to_string(), - kind: CollectionKind::DocumentCollection, }, ); exec( &mut mgr, "New session 'Workspace'", - SessionCommand::New { + SessionCommand::NewSession { name: "Workspace".to_string(), - kind: CollectionKind::DocumentCollection, }, ); - // Copy first item from browser → Favorites - heading("Copy item to Favorites"); - step("Before:"); - print_session(&mgr, "Favorites"); + step("Favorites before paste:"); + if let Some(session) = mgr.session_by_name("Favorites") { + print_session(session, None); + } + // SelectSession source → SelectDocument → CopyDocument → SelectSession target → PasteDocument exec( &mut mgr, - &format!("Copy [0] from '{active_name}' → 'Favorites'"), - SessionCommand::CopyDocument { - source: active_name.clone(), - target: "Favorites".to_string(), - source_index: 0, - target_index: 0, - }, - ); - step("After:"); - print_session(&mgr, "Favorites"); - - // Remove from DirectoryBrowser (should fail) - heading("Remove from DirectoryBrowser (expect error)"); - exec( - &mut mgr, - &format!("Select '{active_name}'"), - SessionCommand::Select { + &format!("SelectSession '{active_name}'"), + SessionCommand::SelectSession { name: active_name.clone(), }, ); exec( &mut mgr, - "RemoveDocument { index: 0 }", - SessionCommand::RemoveDocument { index: 0 }, + "SelectDocument { index: 0 }", + SessionCommand::SelectDocument { index: 0 }, ); - - // Move: Favorites → Workspace (copy + delete) - heading("Move: Favorites → Workspace"); - step("Before:"); - print_session(&mgr, "Favorites"); - print_session(&mgr, "Workspace"); - + exec(&mut mgr, "CopyDocument", SessionCommand::CopyDocument); exec( &mut mgr, - "Copy [0] from 'Favorites' → 'Workspace'", - SessionCommand::CopyDocument { - source: "Favorites".to_string(), - target: "Workspace".to_string(), - source_index: 0, - target_index: 0, - }, - ); - exec( - &mut mgr, - "Select 'Favorites'", - SessionCommand::Select { + "SelectSession 'Favorites'", + SessionCommand::SelectSession { name: "Favorites".to_string(), }, ); + exec(&mut mgr, "PasteDocument", SessionCommand::PasteDocument); + + step("Favorites after paste:"); + print_active_session(&mgr); + + // Move pasted item to front via MoveDocumentTo + exec( &mut mgr, - "RemoveDocument { index: 0 }", - SessionCommand::RemoveDocument { index: 0 }, + "MoveDocumentTo { index: 0 }", + SessionCommand::MoveDocumentTo { index: 0 }, + ); + step("Favorites after MoveDocumentTo(0):"); + print_active_session(&mgr); + + // Remove active document + + exec(&mut mgr, "RemoveDocument", SessionCommand::RemoveDocument); + step("Favorites after RemoveDocument:"); + print_active_session(&mgr); + + // Session operations + + heading("Session operations"); + + exec( + &mut mgr, + &format!("SelectSession '{active_name}'"), + SessionCommand::SelectSession { + name: active_name.clone(), + }, + ); + exec( + &mut mgr, + "DuplicateSession 'Snapshot'", + SessionCommand::DuplicateSession { + new_name: "Snapshot".to_string(), + }, ); - step("After:"); - print_session(&mgr, "Favorites"); - print_session(&mgr, "Workspace"); + step("Snapshot session:"); + if let Some(session) = mgr.session_by_name("Snapshot") { + print_session(session, None); + } + + exec( + &mut mgr, + "SelectSession 'Workspace'", + SessionCommand::SelectSession { + name: "Workspace".to_string(), + }, + ); + exec( + &mut mgr, + "RenameSession 'Archive'", + SessionCommand::RenameSession { + name: "Archive".to_string(), + }, + ); + + step("All sessions after rename:"); + for session in mgr.sessions() { + let is_active = mgr + .active_session() + .map_or(false, |a| a.name == session.name); + let marker = if is_active { + format!("{GREEN}*{RESET}") + } else { + format!("{DIM} {RESET}") + }; + println!(" {marker} {}", session.name); + } + + exec( + &mut mgr, + "CloseSession (closes 'Archive')", + SessionCommand::CloseSession, + ); + + step("All sessions after close:"); + for session in mgr.sessions() { + println!(" {DIM}-{RESET} {}", session.name); + } heading("Done"); }