use iced::widget::text_editor;
use iced::window;
use quincy::config::ClientConfig;
use std::fmt;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Instant;
use tokio::sync::Mutex;
use super::error::GuiError;
use crate::ipc::{ConnectionMetrics, IpcConnection};
#[derive(Debug, Clone, Default)]
pub enum ConfigState {
#[default]
Idle,
Connecting {
started_at: Instant,
instance: Option<QuincyInstance>,
},
Connected {
instance: QuincyInstance,
metrics: Option<ConnectionMetrics>,
},
Disconnecting,
Error {
error: GuiError,
},
}
impl ConfigState {
pub fn is_connected(&self) -> bool {
matches!(self, Self::Connected { .. })
}
pub fn is_transitioning(&self) -> bool {
matches!(self, Self::Connecting { .. } | Self::Disconnecting)
}
pub fn has_active_instance(&self) -> bool {
matches!(
self,
Self::Connecting { .. } | Self::Connected { .. } | Self::Disconnecting
)
}
pub fn instance(&self) -> Option<&QuincyInstance> {
match self {
Self::Connected { instance, .. } => Some(instance),
_ => None,
}
}
pub fn instance_mut(&mut self) -> Option<&mut QuincyInstance> {
match self {
Self::Connected { instance, .. } => Some(instance),
_ => None,
}
}
pub fn metrics(&self) -> Option<&ConnectionMetrics> {
match self {
Self::Connected { metrics, .. } => metrics.as_ref(),
_ => None,
}
}
pub fn error(&self) -> Option<&GuiError> {
match self {
Self::Error { error } => Some(error),
_ => None,
}
}
}
#[derive(Clone)]
pub struct QuincyInstance {
pub name: String,
pub(crate) ipc_client: Option<Arc<Mutex<IpcConnection>>>,
}
impl fmt::Debug for QuincyInstance {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("QuincyInstance")
.field("name", &self.name)
.field("has_ipc", &self.ipc_client.is_some())
.finish()
}
}
impl QuincyInstance {
pub fn new(name: String, ipc_client: Option<Arc<Mutex<IpcConnection>>>) -> Self {
Self { name, ipc_client }
}
pub fn ipc_client(&self) -> Option<&Arc<Mutex<IpcConnection>>> {
self.ipc_client.as_ref()
}
pub fn take_ipc_client(&mut self) -> Option<Arc<Mutex<IpcConnection>>> {
self.ipc_client.take()
}
}
#[derive(Clone)]
pub struct QuincyConfig {
pub name: String,
pub path: PathBuf,
}
pub struct ConfigEntry {
pub config: QuincyConfig,
pub state: ConfigState,
pub parsed: Option<ClientConfig>,
pub parse_error: Option<String>,
}
#[derive(Debug)]
pub struct EditorState {
pub config_name: String,
pub content: text_editor::Content,
}
#[derive(Debug, Clone)]
pub struct ConfirmationState {
pub title: String,
pub message: String,
pub confirm_action: ConfirmAction,
}
#[derive(Debug, Clone)]
pub enum ConfirmAction {
DeleteConfig(String), DiscardEditorChanges,
}
#[derive(Debug, Clone)]
pub enum ConfigMsg {
Selected(String),
NameChanged(String),
NameSaved,
Delete,
New,
}
#[derive(Debug, Clone)]
pub enum ConfirmMsg {
Show(ConfirmationState),
Confirm,
Cancel,
}
#[derive(Debug, Clone)]
pub enum EditorMsg {
Action(text_editor::Action),
Open,
Close,
Save,
}
#[derive(Debug, Clone)]
pub enum InstanceMsg {
Connect,
Connected(String),
ConnectedInstance(QuincyInstance, Option<ConnectionMetrics>),
Disconnect,
CancelConnect,
Disconnected,
StatusUpdated(String, Option<ConnectionMetrics>),
DisconnectedWithError(String, GuiError),
ConnectFailed(String, GuiError),
}
#[derive(Debug, Clone)]
pub enum SystemMsg {
WindowClosed(window::Id),
UpdateMetrics,
Noop,
}
#[derive(Debug, Clone)]
pub enum Message {
Config(ConfigMsg),
Editor(EditorMsg),
Instance(InstanceMsg),
System(SystemMsg),
Confirm(ConfirmMsg),
}