use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct Config {
#[serde(default)]
pub defaults: Defaults,
#[serde(default)]
pub clusters: HashMap<String, Cluster>,
#[serde(default)]
pub interactive: InteractiveConfig,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct Defaults {
pub user: Option<String>,
pub port: Option<u16>,
pub ssh_key: Option<String>,
pub parallel: Option<usize>,
pub timeout: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct InteractiveConfig {
#[serde(default = "default_interactive_mode")]
pub default_mode: InteractiveMode,
#[serde(default = "default_prompt_format")]
pub prompt_format: String,
#[serde(default)]
pub history_file: Option<String>,
#[serde(default)]
pub colors: HashMap<String, String>,
#[serde(default)]
pub keybindings: KeyBindings,
#[serde(default)]
pub broadcast_prefix: Option<String>,
#[serde(default)]
pub node_switch_prefix: Option<String>,
#[serde(default)]
pub show_timestamps: bool,
#[serde(default)]
pub work_dir: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(rename_all = "snake_case")]
#[derive(Default)]
pub enum InteractiveMode {
#[default]
SingleNode,
Multiplex,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct KeyBindings {
#[serde(default = "default_switch_node")]
pub switch_node: String,
#[serde(default = "default_broadcast_toggle")]
pub broadcast_toggle: String,
#[serde(default = "default_quit")]
pub quit: String,
#[serde(default)]
pub clear_screen: Option<String>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Cluster {
pub nodes: Vec<NodeConfig>,
#[serde(flatten)]
pub defaults: ClusterDefaults,
#[serde(default)]
pub interactive: Option<InteractiveConfig>,
}
#[derive(Debug, Serialize, Deserialize, Default, Clone)]
pub struct ClusterDefaults {
pub user: Option<String>,
pub port: Option<u16>,
pub ssh_key: Option<String>,
pub parallel: Option<usize>,
pub timeout: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(untagged)]
pub enum NodeConfig {
Simple(String),
Detailed {
host: String,
#[serde(default)]
port: Option<u16>,
#[serde(default)]
user: Option<String>,
},
}
#[derive(Debug, Default)]
pub struct InteractiveConfigUpdate {
pub default_mode: Option<InteractiveMode>,
pub prompt_format: Option<String>,
pub history_file: Option<String>,
pub work_dir: Option<String>,
pub show_timestamps: Option<bool>,
pub colors: Option<HashMap<String, String>>,
}
pub(super) fn default_interactive_mode() -> InteractiveMode {
InteractiveMode::SingleNode
}
pub(super) fn default_prompt_format() -> String {
"[{node}:{user}@{host}:{pwd}]$ ".to_string()
}
pub(super) fn default_switch_node() -> String {
"Ctrl+N".to_string()
}
pub(super) fn default_broadcast_toggle() -> String {
"Ctrl+B".to_string()
}
pub(super) fn default_quit() -> String {
"Ctrl+Q".to_string()
}