Skip to main content

omnyssh_core/
event.rs

1//! Domain events and their payload types.
2//!
3//! Background tasks (metrics poller, SFTP, PTY sessions, discovery, the
4//! update checker) report back to the frontend by sending [`CoreEvent`]
5//! values over an `mpsc` channel. Frontends wrap these into their own event
6//! type alongside input events.
7
8use std::time::Instant;
9
10use crate::config::snippets::Snippet;
11use crate::ssh::client::{ConnectionStatus, Host};
12use crate::ssh::key_setup::KeySetupStep;
13use crate::ssh::sftp::FileEntry;
14
15/// Placeholder type aliases for future stages.
16/// `HostId` is the host's `name` field — stable, human-readable key.
17pub type HostId = String;
18pub type SessionId = u64;
19pub type TransferId = u64;
20
21/// A single process entry for the "top processes" panel.
22#[derive(Debug, Clone)]
23pub struct ProcessInfo {
24    /// Process / command name.
25    pub name: String,
26    /// CPU usage percentage.
27    pub cpu_percent: f64,
28    /// Memory usage percentage.
29    pub mem_percent: f64,
30}
31
32/// Live metrics collected from a remote server.
33#[derive(Debug, Clone)]
34pub struct Metrics {
35    pub cpu_percent: Option<f64>,
36    pub ram_percent: Option<f64>,
37    pub disk_percent: Option<f64>,
38    pub uptime: Option<String>,
39    pub load_avg: Option<String>,
40    /// OS information (e.g., "Ubuntu 22.04 LTS", "Debian GNU/Linux 11").
41    pub os_info: Option<String>,
42    /// Top processes by CPU usage (at most 3).
43    pub top_processes: Option<Vec<ProcessInfo>>,
44    /// When these metrics were last successfully collected.
45    pub last_updated: Instant,
46}
47
48impl Default for Metrics {
49    fn default() -> Self {
50        Self {
51            cpu_percent: None,
52            ram_percent: None,
53            disk_percent: None,
54            uptime: None,
55            load_avg: None,
56            os_info: None,
57            top_processes: None,
58            last_updated: Instant::now(),
59        }
60    }
61}
62
63/// Domain events produced by the SSH engine, config loaders, and the update
64/// checker. Background tasks send these over a dedicated channel; the
65/// frontend wraps them into its own event stream.
66#[derive(Debug)]
67pub enum CoreEvent {
68    /// SSH metrics received from a background task.
69    MetricsUpdate(HostId, Metrics),
70    /// Connection status changed for a host (reported by metrics poller).
71    HostStatusChanged(HostId, ConnectionStatus),
72    /// File transfer progress: (transfer_id, bytes_done, bytes_total).
73    FileTransferProgress(TransferId, u64, u64),
74    /// An error message surfaced to the user.
75    Error(String),
76    /// Host list loaded from disk / SSH config in a background task.
77    HostsLoaded(Vec<Host>),
78    /// Snippet list loaded from disk in a background task.
79    SnippetsLoaded(Vec<Snippet>),
80    /// Result of executing a snippet or quick-execute command on one host.
81    /// `output` is `Ok(stdout)` or `Err(error_message)`.
82    SnippetResult {
83        host_name: String,
84        snippet_name: String,
85        output: Result<String, String>,
86    },
87
88    // -----------------------------------------------------------------------
89    // File Manager events
90    // -----------------------------------------------------------------------
91    /// Remote directory listing completed.
92    FileDirListed {
93        path: String,
94        entries: Vec<FileEntry>,
95    },
96    /// Local directory listing completed.
97    LocalDirListed {
98        path: String,
99        entries: Vec<FileEntry>,
100    },
101    /// SFTP session successfully established.
102    SftpConnected { host_name: String },
103    /// SFTP manager ready with established connection (contains SftpManager handle).
104    SftpManagerReady {
105        host_name: String,
106        manager: Box<crate::ssh::sftp::SftpManager>,
107    },
108    /// SFTP session closed or failed.
109    SftpDisconnected { reason: String },
110    /// Preview bytes available for a file.
111    FilePreviewReady { path: String, content: String },
112    /// A mutating SFTP operation (delete, mkdir, rename, upload, download) finished.
113    SftpOpDone { result: Result<(), String> },
114
115    // -----------------------------------------------------------------------
116    // PTY multi-session terminal events
117    // -----------------------------------------------------------------------
118    /// A PTY session produced output. The bytes are already parsed into the
119    /// session's `Arc<Mutex<vt100::Parser>>`; this event is a lightweight
120    /// render-nudge so the main loop can update `has_activity` state without
121    /// copying bulk output data through the channel.
122    PtyOutput(SessionId),
123    /// The PTY child process exited (reader thread reached EOF or I/O error).
124    PtyExited(SessionId),
125
126    // -----------------------------------------------------------------------
127    // Smart Server Context — Discovery events
128    // -----------------------------------------------------------------------
129    /// Quick scan completed for a host, services detected.
130    DiscoveryQuickScanDone(HostId, Vec<DetectedService>),
131    /// Discovery failed for a host with an error message.
132    DiscoveryFailed(HostId, String),
133
134    // -----------------------------------------------------------------------
135    // Auto SSH Key Setup events
136    // -----------------------------------------------------------------------
137    /// Progress update from key setup (host_id, current step, total steps).
138    KeySetupProgress(HostId, KeySetupStep),
139    /// Key setup completed successfully (host_id, private_key_path).
140    KeySetupComplete(HostId, std::path::PathBuf),
141    /// Key setup failed with an error (host_id, error_message).
142    KeySetupFailed(HostId, String),
143    /// Emergency rollback was triggered (host_id, rollback_result).
144    KeySetupRollback(HostId, String),
145
146    // -----------------------------------------------------------------------
147    // Update checker events
148    // -----------------------------------------------------------------------
149    /// A newer release was found on GitHub at startup.
150    UpdateAvailable(crate::update::UpdateInfo),
151    /// A self-update finished — `Ok` on success, `Err` with a message on failure.
152    UpdateInstalled(Result<(), String>),
153}
154
155// ---------------------------------------------------------------------------
156// Smart Server Context — Data structures
157// ---------------------------------------------------------------------------
158
159/// Describes a service detected on a remote server.
160#[derive(Debug, Clone)]
161pub struct DetectedService {
162    pub kind: ServiceKind,
163    pub metrics: Vec<ServiceMetric>,
164}
165
166/// Type of service detected on the server.
167/// Only 5 core services are supported: Docker, Nginx, PostgreSQL, Redis, Node.js.
168#[derive(Debug, Clone, PartialEq, Eq, Hash)]
169pub enum ServiceKind {
170    Docker,
171    Nginx,
172    PostgreSQL,
173    Redis,
174    NodeJS,
175}
176
177/// A metric collected from a specific service.
178#[derive(Debug, Clone)]
179pub struct ServiceMetric {
180    pub name: String,       // e.g., "containers_running"
181    pub value: MetricValue, // Typed value
182}
183
184/// Typed metric value.
185#[derive(Debug, Clone)]
186pub enum MetricValue {
187    Integer(i64),
188}