//! IPC (Inter-Process Communication) types for Tauri commands use serde::{Deserialize, Serialize}; use crate::jobs::JobStatus; use crate::slide::SlideStatus; /// Service status response #[derive(Debug, Clone, Serialize, Deserialize, Default)] pub struct SlidescopeStatus { /// Whether the service is initialized pub initialized: bool, /// Whether GPU is available pub gpu_available: bool, /// GPU device name if available pub gpu_name: Option, /// Number of slides in registry pub slide_count: usize, /// Number of pending jobs pub pending_jobs: usize, /// Currently active job ID pub active_job: Option, /// Workspace directory pub workspace: Option, /// Service uptime in seconds pub uptime_secs: u64, } /// Filter options for listing slides #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct SlideFilter { /// Filter by status pub status: Option, /// Search by name (partial match) pub name_contains: Option, /// Limit number of results pub limit: Option, /// Offset for pagination pub offset: Option, } /// Batch operation result #[derive(Debug, Clone, Serialize, Deserialize)] pub struct BatchResult { /// Number of successful operations pub succeeded: usize, /// Number of failed operations pub failed: usize, /// Error messages for failures pub errors: Vec, } /// Import options for slide import #[derive(Debug, Clone, Default, Serialize, Deserialize)] pub struct ImportOptions { /// Auto-detect stain type pub auto_detect_stain: bool, /// Generate thumbnail pub generate_thumbnail: bool, /// Thumbnail size (default 256) pub thumbnail_size: Option, /// Custom name override pub name: Option, } impl ImportOptions { /// Default import with all features enabled pub fn default_with_all() -> Self { Self { auto_detect_stain: true, generate_thumbnail: true, thumbnail_size: Some(256), name: None, } } } /// Export format for results #[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)] #[serde(rename_all = "lowercase")] #[derive(Default)] pub enum ExportFormat { /// TIFF with all stain layers #[default] Tiff, /// PNG images Png, /// JPEG images Jpeg, /// JSON metadata only Json, } /// Export request for results #[derive(Debug, Clone, Serialize, Deserialize)] pub struct ExportRequest { /// Slide ID to export pub slide_id: String, /// Output directory pub output_dir: String, /// Export format pub format: ExportFormat, /// Include original image pub include_original: bool, /// Include stain layers pub include_stains: bool, /// Include composite pub include_composite: bool, } /// Queue status summary #[derive(Debug, Clone, Serialize, Deserialize)] pub struct QueueStatus { /// Jobs currently in queue pub queued: Vec, /// Currently processing job pub active: Option, /// Recently completed jobs pub recent_completed: Vec, } #[cfg(test)] mod tests { use super::*; #[test] fn test_slidescope_status_default() { let status = SlidescopeStatus::default(); assert!(!status.initialized); assert!(!status.gpu_available); assert_eq!(status.slide_count, 0); } #[test] fn test_slide_filter_serialization() { let filter = SlideFilter { status: Some(SlideStatus::Imported), name_contains: Some("sample".to_string()), limit: Some(10), offset: None, }; let json = serde_json::to_string(&filter).unwrap(); let deserialized: SlideFilter = serde_json::from_str(&json).unwrap(); assert_eq!(deserialized.status, Some(SlideStatus::Imported)); } #[test] fn test_export_format() { let format = ExportFormat::Tiff; let json = serde_json::to_string(&format).unwrap(); assert_eq!(json, "\"tiff\""); } #[test] fn test_import_options() { let opts = ImportOptions::default_with_all(); assert!(opts.auto_detect_stain); assert!(opts.generate_thumbnail); } }