Skip to main content

e_book_sync_library/
config.rs

1//! Config entity
2//!
3//! Main config storage - store synchronization paths
4
5use std::fs::File;
6use std::io::prelude::*;
7use std::path::PathBuf;
8
9use serde::{Deserialize, Serialize};
10
11pub struct Config {
12    path: PathBuf,
13}
14
15#[derive(Serialize, Deserialize)]
16pub struct ConfigStorage {
17    source: PathBuf,
18    destination: PathBuf,
19}
20
21impl Config {
22    pub fn new(path: PathBuf) -> Self {
23        Config { path }
24    }
25
26    pub fn parse(&self) -> Result<(PathBuf, PathBuf), String> {
27        if !self.path.exists() {
28            return Err(format!(
29                "Script: {} doesn't exist",
30                self.path.to_str().unwrap()
31            ));
32        }
33
34        let mut f = File::open(self.path.clone())
35            .or_else(|e| Err(format!("fail to open config with error: {}", e)))?;
36
37        let mut s = String::new();
38        f.read_to_string(&mut s)
39            .or_else(|e| Err(format!("fail to read config with error: {}", e)))?;
40
41        let ConfigStorage {
42            source,
43            destination,
44        } = serde_yaml::from_str(&s)
45            .or_else(|e| Err(format!("fail to parse config with error: {}", e)))?;
46
47        Ok((source, destination))
48    }
49
50    pub fn store(&self, source: PathBuf, destination: PathBuf) -> Result<(), String> {
51        let mut f = File::create(self.path.clone())
52            .or_else(|e| Err(format!("fail to create config with error: {}", e)))?;
53
54        let config = ConfigStorage {
55            source,
56            destination,
57        };
58
59        let serialized = serde_yaml::to_string(&config)
60            .or_else(|e| Err(format!("fail to serialize config with error: {}", e)))?;
61
62        match f.write_all(serialized.as_bytes()) {
63            Ok(_) => Ok(()),
64            Err(e) => Err(format!("fail to store config with error: {}", e)),
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use std::path::PathBuf;
72
73    use super::Config;
74
75    #[test]
76    fn parse() {
77        let cfg = Config::new(PathBuf::from("tests/config/test_config.yaml"));
78
79        let (source, destination) = cfg.parse().unwrap();
80
81        assert_eq!(source, PathBuf::from("/test/path/to_source"));
82        assert_eq!(destination, PathBuf::from("/test/path/to_destination"));
83    }
84
85    #[test]
86    fn store() {
87        let cfg = Config::new(PathBuf::from("tests/config/test_config_store.yaml"));
88
89        let source = PathBuf::from("/test/path/to_source");
90        let destination = PathBuf::from("/test/path/to_destination");
91
92        assert_eq!(cfg.store(source.clone(), destination.clone()), Ok(()));
93
94        let (source, destination) = cfg.parse().unwrap();
95
96        assert_eq!(source, PathBuf::from("/test/path/to_source"));
97        assert_eq!(destination, PathBuf::from("/test/path/to_destination"));
98    }
99}