bssh/config/
types.rs

1// Copyright 2025 Lablup Inc. and Jeongkyu Shin
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15//! Configuration type definitions.
16
17use serde::{Deserialize, Serialize};
18use std::collections::HashMap;
19
20/// Main configuration structure.
21#[derive(Debug, Serialize, Deserialize, Default, Clone)]
22pub struct Config {
23    #[serde(default)]
24    pub defaults: Defaults,
25
26    #[serde(default)]
27    pub clusters: HashMap<String, Cluster>,
28
29    #[serde(default)]
30    pub interactive: InteractiveConfig,
31}
32
33/// Global default settings.
34#[derive(Debug, Serialize, Deserialize, Default, Clone)]
35pub struct Defaults {
36    pub user: Option<String>,
37    pub port: Option<u16>,
38    pub ssh_key: Option<String>,
39    pub parallel: Option<usize>,
40    pub timeout: Option<u64>,
41}
42
43/// Interactive mode configuration.
44#[derive(Debug, Serialize, Deserialize, Default, Clone)]
45pub struct InteractiveConfig {
46    #[serde(default = "default_interactive_mode")]
47    pub default_mode: InteractiveMode,
48
49    #[serde(default = "default_prompt_format")]
50    pub prompt_format: String,
51
52    #[serde(default)]
53    pub history_file: Option<String>,
54
55    #[serde(default)]
56    pub colors: HashMap<String, String>,
57
58    #[serde(default)]
59    pub keybindings: KeyBindings,
60
61    #[serde(default)]
62    pub broadcast_prefix: Option<String>,
63
64    #[serde(default)]
65    pub node_switch_prefix: Option<String>,
66
67    #[serde(default)]
68    pub show_timestamps: bool,
69
70    #[serde(default)]
71    pub work_dir: Option<String>,
72}
73
74/// Interactive mode type.
75#[derive(Debug, Serialize, Deserialize, Clone)]
76#[serde(rename_all = "snake_case")]
77#[derive(Default)]
78pub enum InteractiveMode {
79    #[default]
80    SingleNode,
81    Multiplex,
82}
83
84/// Keyboard bindings configuration.
85#[derive(Debug, Serialize, Deserialize, Default, Clone)]
86pub struct KeyBindings {
87    #[serde(default = "default_switch_node")]
88    pub switch_node: String,
89
90    #[serde(default = "default_broadcast_toggle")]
91    pub broadcast_toggle: String,
92
93    #[serde(default = "default_quit")]
94    pub quit: String,
95
96    #[serde(default)]
97    pub clear_screen: Option<String>,
98}
99
100/// Cluster configuration.
101#[derive(Debug, Serialize, Deserialize, Clone)]
102pub struct Cluster {
103    pub nodes: Vec<NodeConfig>,
104
105    #[serde(flatten)]
106    pub defaults: ClusterDefaults,
107
108    #[serde(default)]
109    pub interactive: Option<InteractiveConfig>,
110}
111
112/// Cluster-specific default settings.
113#[derive(Debug, Serialize, Deserialize, Default, Clone)]
114pub struct ClusterDefaults {
115    pub user: Option<String>,
116    pub port: Option<u16>,
117    pub ssh_key: Option<String>,
118    pub parallel: Option<usize>,
119    pub timeout: Option<u64>,
120}
121
122/// Node configuration within a cluster.
123#[derive(Debug, Serialize, Deserialize, Clone)]
124#[serde(untagged)]
125pub enum NodeConfig {
126    Simple(String),
127    Detailed {
128        host: String,
129        #[serde(default)]
130        port: Option<u16>,
131        #[serde(default)]
132        user: Option<String>,
133    },
134}
135
136/// Structure for updating interactive configuration preferences.
137#[derive(Debug, Default)]
138pub struct InteractiveConfigUpdate {
139    pub default_mode: Option<InteractiveMode>,
140    pub prompt_format: Option<String>,
141    pub history_file: Option<String>,
142    pub work_dir: Option<String>,
143    pub show_timestamps: Option<bool>,
144    pub colors: Option<HashMap<String, String>>,
145}
146
147// Default value functions for serde
148pub(super) fn default_interactive_mode() -> InteractiveMode {
149    InteractiveMode::SingleNode
150}
151
152pub(super) fn default_prompt_format() -> String {
153    "[{node}:{user}@{host}:{pwd}]$ ".to_string()
154}
155
156pub(super) fn default_switch_node() -> String {
157    "Ctrl+N".to_string()
158}
159
160pub(super) fn default_broadcast_toggle() -> String {
161    "Ctrl+B".to_string()
162}
163
164pub(super) fn default_quit() -> String {
165    "Ctrl+Q".to_string()
166}