use std::fmt::Display;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Deserialize, Serialize, Default, PartialEq)]
pub enum ConfigOrigin {
#[default]
GalionConfig,
RcloneConfig,
}
impl Display for ConfigOrigin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::GalionConfig => write!(f, "galion config"),
Self::RcloneConfig => write!(f, "rclone config"),
}
}
}
#[derive(Debug, Clone, Deserialize, Serialize)]
pub struct RemoteConfiguration {
pub remote_name: String,
pub remote_src: Option<String>,
pub remote_dest: Option<String>,
#[serde(skip)]
pub config_origin: ConfigOrigin,
}
impl RemoteConfiguration {
pub fn to_table_row(&self) -> [String; 3] {
[
format!("{}\n{}", self.remote_name, self.config_origin),
self.remote_src.clone().unwrap_or_default(),
self.remote_dest.clone().unwrap_or_default(),
]
}
}
#[derive(Debug)]
pub(crate) struct EditRemote {
pub(crate) idx_string: usize,
pub(crate) character_index: usize,
pub(crate) remote_name: String,
pub(crate) remote_src: String,
pub(crate) remote_dest: String,
}
impl EditRemote {
fn byte_index(&mut self) -> usize {
let input = match self.idx_string {
0 => &mut self.remote_name,
1 => &mut self.remote_src,
_ => &mut self.remote_dest,
};
input
.char_indices()
.map(|(i, _)| i)
.nth(self.character_index)
.unwrap_or(input.len())
}
pub fn enter_char(&mut self, new_char: char) {
let index = self.byte_index();
let input = match self.idx_string {
0 => &mut self.remote_name,
1 => &mut self.remote_src,
_ => &mut self.remote_dest,
};
input.insert(index, new_char);
self.move_cursor_right();
}
fn clamp_cursor(&self, new_cursor_pos: usize) -> usize {
let input_count = match self.idx_string {
0 => self.remote_name.chars().count(),
1 => self.remote_src.chars().count(),
_ => self.remote_dest.chars().count(),
};
new_cursor_pos.clamp(0, input_count)
}
pub fn move_cursor_right(&mut self) {
let cursor_moved_right = self.character_index.saturating_add(1);
self.character_index = self.clamp_cursor(cursor_moved_right);
}
pub fn move_cursor_left(&mut self) {
let cursor_moved_left = self.character_index.saturating_sub(1);
self.character_index = self.clamp_cursor(cursor_moved_left);
}
pub fn delete_char(&mut self) {
let is_not_cursor_leftmost = self.character_index != 0;
if is_not_cursor_leftmost {
let input = match self.idx_string {
0 => &mut self.remote_name,
1 => &mut self.remote_src,
_ => &mut self.remote_dest,
};
let current_index = self.character_index;
let from_left_to_current_index = current_index - 1;
let before_char_to_delete = input.chars().take(from_left_to_current_index);
let after_char_to_delete = input.chars().skip(current_index);
*input = before_char_to_delete.chain(after_char_to_delete).collect();
self.move_cursor_left();
}
}
pub fn reset_char_index(&mut self) {
let input_len = match self.idx_string {
0 => self.remote_name.chars().count(),
1 => self.remote_src.chars().count(),
_ => self.remote_dest.chars().count(),
};
self.character_index = self.clamp_cursor(input_len);
}
pub fn finish(&self) -> RemoteConfiguration {
RemoteConfiguration {
remote_name: self.remote_name.clone(),
remote_src: Some(self.remote_src.clone()),
remote_dest: Some(self.remote_dest.clone()),
config_origin: ConfigOrigin::GalionConfig,
}
}
}