1use std::fs;
4use std::path::Path;
5
6use crate::user::User;
7
8#[derive(Debug, serde::Serialize, serde::Deserialize)]
9struct UserEntry {
10 name: String,
11 email: String,
12}
13
14#[derive(Debug, serde::Serialize, serde::Deserialize)]
15struct Config {
16 user: Vec<UserEntry>,
17}
18
19pub struct UserFile {
20 path: std::path::PathBuf,
21}
22
23impl UserFile {
24 pub fn new(path: impl AsRef<Path>) -> Self {
25 let path = path.as_ref().to_path_buf();
26 if !path.exists() {
27 let _ = fs::write(&path, "");
28 }
29 UserFile { path }
30 }
31
32 pub fn write(&self, user: &User) -> std::io::Result<()> {
33 let mut config = self.read_config();
34 config.user.push(UserEntry {
35 name: user.name(),
36 email: user.email(),
37 });
38 self.write_config(&config)
39 }
40
41 pub fn read(&self) -> Vec<User> {
42 self.read_config()
43 .user
44 .into_iter()
45 .map(|e| User::new(e.name, e.email))
46 .collect()
47 }
48
49 fn read_config(&self) -> Config {
50 let s = match fs::read_to_string(&self.path) {
51 Ok(s) => s,
52 Err(_) => return Config { user: vec![] },
53 };
54 toml::from_str(&s).unwrap_or(Config { user: vec![] })
55 }
56
57 fn write_config(&self, config: &Config) -> std::io::Result<()> {
58 let s = toml::to_string_pretty(config).unwrap_or_default();
59 fs::write(&self.path, s)
60 }
61}