|
|
@@ -1,14 +1,19 @@
|
|
1
|
1
|
use clap;
|
|
|
2
|
+use directories::ProjectDirs;
|
|
|
3
|
+use std::fmt::Debug;
|
|
2
|
4
|
use std::fs::File;
|
|
3
|
5
|
use std::io::{Read, Write};
|
|
4
|
6
|
use std::path::{Path, PathBuf};
|
|
5
|
7
|
use tile_source::TileSource;
|
|
6
|
8
|
use toml::Value;
|
|
7
|
|
-use xdg;
|
|
8
|
9
|
|
|
9
|
10
|
static DEFAULT_CONFIG: &'static str = "";
|
|
10
|
11
|
static DEFAULT_TILE_SOURCES: &'static str = include_str!("../default_tile_sources.toml");
|
|
11
|
12
|
|
|
|
13
|
+lazy_static! {
|
|
|
14
|
+ static ref PROJ_DIRS: ProjectDirs = ProjectDirs::from("", "", "DeltaMap");
|
|
|
15
|
+}
|
|
|
16
|
+
|
|
12
|
17
|
|
|
13
|
18
|
#[derive(Debug)]
|
|
14
|
19
|
pub struct Config {
|
|
|
@@ -54,64 +59,87 @@ impl Config {
|
|
54
|
59
|
}
|
|
55
|
60
|
}
|
|
56
|
61
|
|
|
|
62
|
+ fn create_config_file<P: AsRef<Path> + Debug>(dir_path: P, file_path: P, contents: &[u8]) -> Result<(), String> {
|
|
|
63
|
+ if !dir_path.as_ref().is_dir() {
|
|
|
64
|
+ if let Err(err) = ::std::fs::create_dir_all(&dir_path) {
|
|
|
65
|
+ return Err(format!("failed to create config directory ({:?}): {}",
|
|
|
66
|
+ dir_path,
|
|
|
67
|
+ err
|
|
|
68
|
+ ));
|
|
|
69
|
+ }
|
|
|
70
|
+ }
|
|
|
71
|
+
|
|
|
72
|
+ let mut file = File::create(&file_path)
|
|
|
73
|
+ .map_err(|err| format!("failed to create config file {:?}: {}", &file_path, err))?;
|
|
|
74
|
+
|
|
|
75
|
+ file.write_all(contents)
|
|
|
76
|
+ .map_err(|err| format!(
|
|
|
77
|
+ "failed to write contents to config file {:?}: {}",
|
|
|
78
|
+ &file_path,
|
|
|
79
|
+ err
|
|
|
80
|
+ ))
|
|
|
81
|
+ }
|
|
|
82
|
+
|
|
57
|
83
|
fn find_or_create() -> Result<Config, String> {
|
|
58
|
|
- if let Ok(xdg_dirs) = xdg::BaseDirectories::with_prefix("deltamap") {
|
|
59
|
|
- if let Some(config_path) = xdg_dirs.find_config_file("config.toml") {
|
|
60
|
|
- info!("load config from path {:?}", config_path);
|
|
61
|
|
-
|
|
62
|
|
- Config::from_toml_file(config_path)
|
|
63
|
|
- } else {
|
|
64
|
|
- // try to write a default config file
|
|
65
|
|
- if let Ok(path) = xdg_dirs.place_config_file("config.toml") {
|
|
66
|
|
- if let Ok(mut file) = File::create(&path) {
|
|
67
|
|
- if file.write_all(DEFAULT_CONFIG.as_bytes()).is_ok() {
|
|
68
|
|
- info!("write default config to {:?}", &path);
|
|
69
|
|
- }
|
|
70
|
|
- }
|
|
71
|
|
- }
|
|
|
84
|
+ let config_dir = PROJ_DIRS.config_dir();
|
|
|
85
|
+ let config_file = {
|
|
|
86
|
+ let mut path = PathBuf::from(config_dir);
|
|
|
87
|
+ path.push("config.toml");
|
|
|
88
|
+ path
|
|
|
89
|
+ };
|
|
72
|
90
|
|
|
73
|
|
- Config::from_toml_str(DEFAULT_CONFIG)
|
|
74
|
|
- }
|
|
|
91
|
+ if config_file.is_file() {
|
|
|
92
|
+ info!("load config from path {:?}", config_file);
|
|
|
93
|
+
|
|
|
94
|
+ Config::from_toml_file(config_file)
|
|
75
|
95
|
} else {
|
|
76
|
|
- info!("load default config");
|
|
|
96
|
+ // try to write a default config file
|
|
|
97
|
+
|
|
|
98
|
+ if let Err(err) = Config::create_config_file(
|
|
|
99
|
+ config_dir,
|
|
|
100
|
+ &config_file,
|
|
|
101
|
+ DEFAULT_CONFIG.as_bytes())
|
|
|
102
|
+ {
|
|
|
103
|
+ warn!("{}", err);
|
|
|
104
|
+ }
|
|
|
105
|
+
|
|
77
|
106
|
Config::from_toml_str(DEFAULT_CONFIG)
|
|
78
|
107
|
}
|
|
79
|
108
|
}
|
|
80
|
109
|
|
|
81
|
110
|
fn add_tile_sources_from_default_or_create(&mut self) -> Result<(), String> {
|
|
82
|
|
- if let Ok(xdg_dirs) = xdg::BaseDirectories::with_prefix("deltamap") {
|
|
83
|
|
- if let Some(sources_path) = xdg_dirs.find_config_file("tile_sources.toml") {
|
|
84
|
|
- info!("load tile sources from path {:?}", sources_path);
|
|
85
|
|
-
|
|
86
|
|
- self.add_tile_sources_from_file(sources_path)
|
|
87
|
|
- } else {
|
|
88
|
|
- // try to write a default tile sources file
|
|
89
|
|
- if let Ok(path) = xdg_dirs.place_config_file("tile_sources.toml") {
|
|
90
|
|
- if let Ok(mut file) = File::create(&path) {
|
|
91
|
|
- if file.write_all(DEFAULT_TILE_SOURCES.as_bytes()).is_ok() {
|
|
92
|
|
- info!("write default tile sources to {:?}", &path);
|
|
93
|
|
- }
|
|
94
|
|
- }
|
|
95
|
|
- }
|
|
|
111
|
+ let config_dir = PROJ_DIRS.config_dir();
|
|
|
112
|
+ let sources_file = {
|
|
|
113
|
+ let mut path = PathBuf::from(config_dir);
|
|
|
114
|
+ path.push("tile_sources.toml");
|
|
|
115
|
+ path
|
|
|
116
|
+ };
|
|
96
|
117
|
|
|
97
|
|
- self.add_tile_sources_from_str(DEFAULT_TILE_SOURCES)
|
|
98
|
|
- }
|
|
|
118
|
+ if sources_file.is_file() {
|
|
|
119
|
+ info!("load tile sources from path {:?}", sources_file);
|
|
|
120
|
+
|
|
|
121
|
+ self.add_tile_sources_from_file(sources_file)
|
|
99
|
122
|
} else {
|
|
100
|
|
- info!("load default config");
|
|
|
123
|
+ // try to write a default config file
|
|
|
124
|
+
|
|
|
125
|
+ if let Err(err) = Config::create_config_file(
|
|
|
126
|
+ config_dir,
|
|
|
127
|
+ &sources_file,
|
|
|
128
|
+ DEFAULT_TILE_SOURCES.as_bytes())
|
|
|
129
|
+ {
|
|
|
130
|
+ warn!("{}", err);
|
|
|
131
|
+ }
|
|
|
132
|
+
|
|
101
|
133
|
self.add_tile_sources_from_str(DEFAULT_TILE_SOURCES)
|
|
102
|
134
|
}
|
|
103
|
135
|
}
|
|
104
|
136
|
|
|
105
|
|
- /// Returns a tile cache directory path at a standard XDG cache location. The returned path may
|
|
106
|
|
- /// not exist.
|
|
107
|
|
- fn default_tile_cache_dir() -> Result<PathBuf, String> {
|
|
108
|
|
- let xdg_dirs = xdg::BaseDirectories::with_prefix("deltamap")
|
|
109
|
|
- .map_err(|e| format!("{}", e))?;
|
|
110
|
|
-
|
|
111
|
|
- match xdg_dirs.find_cache_file("tiles") {
|
|
112
|
|
- Some(dir) => Ok(dir),
|
|
113
|
|
- None => Ok(xdg_dirs.get_cache_home().join("tiles")),
|
|
114
|
|
- }
|
|
|
137
|
+ /// Returns a tile cache directory path at a standard location. The returned path may not
|
|
|
138
|
+ /// exist.
|
|
|
139
|
+ fn default_tile_cache_dir() -> PathBuf {
|
|
|
140
|
+ let mut path = PathBuf::from(PROJ_DIRS.cache_dir());
|
|
|
141
|
+ path.push("tiles");
|
|
|
142
|
+ path
|
|
115
|
143
|
}
|
|
116
|
144
|
|
|
117
|
145
|
fn from_toml_str(toml_str: &str) -> Result<Config, String> {
|
|
|
@@ -125,7 +153,7 @@ impl Config {
|
|
125
|
153
|
.ok_or_else(|| "tile_cache_dir has to be a string".to_string())?
|
|
126
|
154
|
)
|
|
127
|
155
|
},
|
|
128
|
|
- None => Config::default_tile_cache_dir()?,
|
|
|
156
|
+ None => Config::default_tile_cache_dir(),
|
|
129
|
157
|
}
|
|
130
|
158
|
};
|
|
131
|
159
|
|