aboutsummaryrefslogtreecommitdiffstats
path: root/src/db.rs
diff options
context:
space:
mode:
authorJesse Luehrs <doy@tozt.net>2020-04-10 03:12:48 -0400
committerJesse Luehrs <doy@tozt.net>2020-04-10 03:12:48 -0400
commit9f7e2803df80e1f6e446c638dca2f884c965a821 (patch)
tree03872e81096fee84dd88bea31338539117d85222 /src/db.rs
parentb3a04c4a143c34ba92008cf018eed159f87a0c6e (diff)
downloadrbw-9f7e2803df80e1f6e446c638dca2f884c965a821.tar.gz
rbw-9f7e2803df80e1f6e446c638dca2f884c965a821.zip
save sync data to local file
Diffstat (limited to 'src/db.rs')
-rw-r--r--src/db.rs83
1 files changed, 83 insertions, 0 deletions
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<String>,
+ pub refresh_token: Option<String>,
+
+ pub iterations: Option<u32>,
+ pub protected_key: Option<String>,
+
+ pub ciphers: Vec<crate::api::Cipher>,
+}
+
+impl Db {
+ pub fn new() -> Self {
+ Self::default()
+ }
+
+ pub fn load(email: &str) -> Result<Self> {
+ 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<Self> {
+ 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))
+ }
+}