diff options
Diffstat (limited to 'src/database/file')
-rw-r--r-- | src/database/file/mod.rs | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/src/database/file/mod.rs b/src/database/file/mod.rs index ff5ad13..d641779 100644 --- a/src/database/file/mod.rs +++ b/src/database/file/mod.rs @@ -261,10 +261,61 @@ impl Storage for FileStorage { } async fn get_setting<'a>(&self, setting: &'a str, user: &'a str) -> Result<String> { - todo!() + let url = http_types::Url::parse(user).expect("Couldn't parse a URL"); + let mut path = relative_path::RelativePathBuf::new(); + path.push(url.origin().ascii_serialization()); + path.push("settings"); + + let path = path.to_path(&self.root_dir); + let lock = get_lockable_file(File::open(path).await?).await; + let guard = lock.read()?; + + let mut content = String::new(); + (&mut &*guard).read_to_string(&mut content).await?; + drop(guard); + let settings: HashMap<String, String> = serde_json::from_str(&content)?; + // XXX consider returning string slices instead of cloning a string every time + // it might come with a performance hit and/or memory usage inflation + settings.get(setting) + .map(|s| s.clone()) + .ok_or_else(|| StorageError::new(ErrorKind::Backend, "Setting not set")) + } async fn set_setting<'a>(&self, setting: &'a str, user: &'a str, value: &'a str) -> Result<()> { - todo!() + let url = http_types::Url::parse(user).expect("Couldn't parse a URL"); + let mut path = relative_path::RelativePathBuf::new(); + path.push(url.origin().ascii_serialization()); + path.push("settings"); + + let path = path.to_path(&self.root_dir); + + let parent = path.parent().unwrap().to_owned(); + if !spawn_blocking(move || parent.is_dir()).await { + async_std::fs::create_dir_all(path.parent().unwrap()).await?; + } + + let file = OpenOptions::new() + .write(true) + .read(true) + .truncate(false) + .create(true) + .open(&path).await?; + let mut lock = get_lockable_file(file).await; + let mut guard = lock.write()?; + + let mut content = String::new(); + guard.read_to_string(&mut content).await?; + let mut settings: HashMap<String, String> = if content.len() == 0 { + HashMap::default() + } else { + serde_json::from_str(&content)? + }; + + settings.insert(setting.to_string(), value.to_string()); + guard.seek(std::io::SeekFrom::Start(0)).await?; + guard.set_len(0).await?; + guard.write_all(serde_json::to_string(&settings)?.as_bytes()).await?; + Ok(()) } } |