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
use crate::service::ServiceResult; use crate::{api::read_option, api_capnp::store_config}; use serde_derive::{Deserialize, Serialize}; use std::collections::HashMap; use std::fs::{self, File}; use std::io::{self, Read, Write}; use std::path::PathBuf; use zeroize::Zeroize; #[derive(Clone, Debug, Serialize, Deserialize, Zeroize)] #[zeroize(drop)] pub struct StoreConfig { pub name: String, pub store_url: String, pub client_id: String, pub autolock_timeout_secs: u64, pub default_identity_id: Option<String>, } impl StoreConfig { pub fn from_reader(reader: store_config::Reader) -> capnp::Result<StoreConfig> { Ok(StoreConfig { name: reader.get_name()?.to_string(), store_url: reader.get_store_url()?.to_string(), client_id: reader.get_client_id()?.to_string(), autolock_timeout_secs: reader.get_autolock_timeout_secs(), default_identity_id: read_option(reader.get_default_identity_id()?)?.map(ToString::to_string), }) } pub fn to_builder(&self, mut builder: store_config::Builder) -> capnp::Result<()> { builder.set_name(&self.name); builder.set_store_url(&self.store_url); builder.set_client_id(&self.client_id); builder.set_autolock_timeout_secs(self.autolock_timeout_secs); match &self.default_identity_id { Some(default_identity_id) => builder .reborrow() .init_default_identity_id() .set_some(capnp::text::new_reader(default_identity_id.as_bytes())?)?, None => builder.reborrow().init_default_identity_id().set_none(()), } Ok(()) } } #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct Config { pub default_store: Option<String>, pub stores: HashMap<String, StoreConfig>, } pub fn config_file() -> PathBuf { let home_dir = dirs::home_dir().unwrap_or_else(|| PathBuf::from(".")); dirs::config_dir() .map(|configs| configs.join("t-rust-less")) .unwrap_or_else(|| home_dir.join(".t-rust-less")) .join("config.toml") } pub fn read_config() -> ServiceResult<Option<Config>> { let config_file = config_file(); match File::open(&config_file) { Ok(mut index_file) => { let mut content = vec![]; index_file.read_to_end(&mut content)?; Ok(Some(toml::from_slice::<Config>(&content)?)) } Err(ref err) if err.kind() == io::ErrorKind::NotFound => Ok(None), Err(err) => Err(err.into()), } } pub fn write_config(config: &Config) -> io::Result<()> { let content = toml::to_string_pretty(config).unwrap(); let config_file = config_file(); fs::create_dir_all(&config_file.parent().unwrap())?; let mut file = File::create(&config_file)?; file.write_all(content.as_bytes())?; Ok(()) }