From 9f7e2803df80e1f6e446c638dca2f884c965a821 Mon Sep 17 00:00:00 2001 From: Jesse Luehrs Date: Fri, 10 Apr 2020 03:12:48 -0400 Subject: save sync data to local file --- src/db.rs | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 src/db.rs (limited to 'src/db.rs') diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..5fa7856 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,83 @@ +use crate::prelude::*; + +use std::io::{Read as _, Write as _}; +use tokio::io::{AsyncReadExt as _, AsyncWriteExt as _}; + +#[derive(serde::Serialize, serde::Deserialize, Default, Debug)] +pub struct Db { + pub access_token: Option, + pub refresh_token: Option, + + pub iterations: Option, + pub protected_key: Option, + + pub ciphers: Vec, +} + +impl Db { + pub fn new() -> Self { + Self::default() + } + + pub fn load(email: &str) -> Result { + let mut fh = std::fs::File::open(Self::filename(email)) + .context(crate::error::LoadDb)?; + let mut json = String::new(); + fh.read_to_string(&mut json).context(crate::error::LoadDb)?; + let slf: Self = + serde_json::from_str(&json).context(crate::error::LoadDbJson)?; + Ok(slf) + } + + pub async fn load_async(email: &str) -> Result { + let mut fh = tokio::fs::File::open(Self::filename(email)) + .await + .context(crate::error::LoadDbAsync)?; + let mut json = String::new(); + fh.read_to_string(&mut json) + .await + .context(crate::error::LoadDbAsync)?; + let slf: Self = + serde_json::from_str(&json).context(crate::error::LoadDbJson)?; + Ok(slf) + } + + // XXX need to make this atomic + pub fn save(&self, email: &str) -> Result<()> { + let filename = Self::filename(email); + std::fs::create_dir_all(filename.parent().unwrap()) + .context(crate::error::SaveDb)?; + let mut fh = + std::fs::File::create(filename).context(crate::error::SaveDb)?; + fh.write_all( + serde_json::to_string(self) + .context(crate::error::SaveDbJson)? + .as_bytes(), + ) + .context(crate::error::SaveDb)?; + Ok(()) + } + + // XXX need to make this atomic + pub async fn save_async(&self, email: &str) -> Result<()> { + let filename = Self::filename(email); + tokio::fs::create_dir_all(filename.parent().unwrap()) + .await + .context(crate::error::SaveDbAsync)?; + let mut fh = tokio::fs::File::create(filename) + .await + .context(crate::error::SaveDbAsync)?; + fh.write_all( + serde_json::to_string(self) + .context(crate::error::SaveDbJson)? + .as_bytes(), + ) + .await + .context(crate::error::SaveDbAsync)?; + Ok(()) + } + + fn filename(email: &str) -> std::path::PathBuf { + crate::dirs::cache_dir().join(format!("{}.json", email)) + } +} -- cgit v1.2.3-54-g00ecf