1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
use gtk::glib;
use serde::{Deserialize, Serialize};
use std::fs;
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct Server {
pub address: String,
pub password: String,
pub name: Option<String>,
}
impl Server {
pub fn get_name(&self) -> &String {
self.name.as_ref().unwrap_or(&self.address)
}
pub fn empty() -> Server {
Server {
address: "".to_string(),
password: "".to_string(),
name: None,
}
}
}
#[derive(Deserialize, Serialize, Debug, Clone)]
pub struct ConfigFile {
active: usize,
servers: Vec<Server>,
}
impl ConfigFile {
pub fn new() -> ConfigFile {
ConfigFile {
active: 0,
servers: vec![],
}
}
pub fn add_server(&mut self, server: Server) {
self.servers.push(server)
}
pub fn remove_server(&mut self, server_index: usize) {
if self.servers.len() > server_index {
self.servers.remove(server_index);
}
}
pub fn update_server(&mut self, index: usize, server: Server) {
self.servers.get_mut(index).map(|s| *s = server);
}
pub fn active_server(&self) -> Option<Server> {
self.servers.get(self.active).map(|s| s.clone())
}
pub fn move_active(&mut self, delta: i16) {
if delta < 0 {
let result = self.active.checked_sub(delta.wrapping_abs() as usize);
match result {
None => self.active = self.servers.len() - 1,
Some(i) => self.active = i,
}
} else {
let result = self.active.checked_add(delta as usize);
match result {
None => self.active = 0,
Some(i) => {
if i >= self.servers.len() {
self.active = 0;
} else {
self.active = i;
}
}
}
}
}
pub fn server_count(&self) -> usize {
self.servers.len()
}
pub fn get_servers(&self) -> &Vec<Server> {
&self.servers
}
pub fn write(&self) -> Option<()> {
let mut path = glib::user_config_dir();
path.push("pmpdc");
std::fs::create_dir_all(&path).ok();
path.push("config.toml");
let config_str = toml::to_string(&self).ok()?;
fs::write(path, config_str).ok()?;
Some(())
}
}
pub fn read_config() -> Option<ConfigFile> {
match read_v2() {
Some(v2) => Some(v2),
None => read_v1(),
}
}
fn read_v2() -> Option<ConfigFile> {
let mut path = glib::user_config_dir();
path.push("pmpdc/config.toml");
let config: ConfigFile = toml::from_str(&fs::read_to_string(path).ok()?).ok()?;
Some(config)
}
#[derive(Deserialize)]
struct ConfigFileV1 {
server: String,
password: String,
}
fn read_v1() -> Option<ConfigFile> {
let mut path = glib::user_config_dir();
path.push("pmpdc/settings.toml");
let config_v1: ConfigFileV1 = toml::from_str(&fs::read_to_string(path.clone()).ok()?).ok()?;
let mut config = ConfigFile::new();
config.add_server(Server {
address: config_v1.server,
password: config_v1.password,
name: None,
});
// delete old
config.write();
fs::remove_file(path).ok()?;
Some(config)
}