Skip to content

Commit

Permalink
refactor(term): remove duplicat code in cache's load and persis methods
Browse files Browse the repository at this point in the history
  • Loading branch information
ymgyt committed Aug 5, 2024
1 parent 98fa8d5 commit e9445da
Show file tree
Hide file tree
Showing 3 changed files with 88 additions and 69 deletions.
130 changes: 81 additions & 49 deletions crates/synd_term/src/application/cache/mod.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
use std::{borrow::Borrow, io, path::PathBuf};
use std::{
borrow::Borrow,
io,
path::{Path, PathBuf},
};

use serde::{de::DeserializeOwned, Serialize};
use thiserror::Error;

use crate::{
auth::{Credential, CredentialError, Unverified},
auth::{Credential, Unverified},
config,
filesystem::{fsimpl, FileSystem},
ui::components::gh_notifications::GhNotificationFilterOptions,
};

#[derive(Debug, Error)]
pub enum PersistCacheError {
#[error("io error: {path} {io} ")]
Io { path: PathBuf, io: io::Error },
#[error("serialize error: {0}")]
Serialize(#[from] serde_json::Error),
}

#[derive(Debug, Error)]
pub enum LoadCacheError {
#[error("cache entry not found")]
NotFound,
#[error("io error: {path} {io}")]
Io { path: PathBuf, io: io::Error },
#[error("deserialize error: {0}")]
Deserialize(#[from] serde_json::Error),
}

pub struct Cache<FS = fsimpl::FileSystem> {
dir: PathBuf,
fs: FS,
Expand All @@ -31,67 +56,74 @@ where

/// Persist credential in filesystem.
/// This is blocking operation.
pub fn persist_credential(&self, cred: impl Borrow<Credential>) -> Result<(), CredentialError> {
let cred = cred.borrow();
let path = self.credential_file();

self.fs.create_dir_all(self.dir.as_path()).map_err(|err| {
CredentialError::PersistCredential {
io_err: err,
path: self.dir.clone(),
}
})?;

let mut file = self
.fs
.create_file(&path)
.map_err(|err| CredentialError::PersistCredential { io_err: err, path })?;

serde_json::to_writer(&mut file, cred).map_err(CredentialError::Serialize)
}

/// Load credential from filesystem.
/// This is blocking operation.
pub fn load_credential(&self) -> Result<Unverified<Credential>, CredentialError> {
let path = self.credential_file();

let mut file = self
.fs
.open_file(&path)
.map_err(|err| CredentialError::Open { io_err: err, path })?;

serde_json::from_reader::<_, Credential>(&mut file)
.map_err(CredentialError::Deserialize)
.map(Unverified::from)
}

fn credential_file(&self) -> PathBuf {
self.dir.join(config::cache::CREDENTIAL_FILE)
pub fn persist_credential(
&self,
cred: impl Borrow<Credential>,
) -> Result<(), PersistCacheError> {
self.persist(&self.credential_file(), cred.borrow())
}

pub(crate) fn persist_gh_notification_filter_options(
&self,
options: impl Borrow<GhNotificationFilterOptions>,
) -> anyhow::Result<()> {
let options = options.borrow();
let path = self.gh_notification_filter_option_file();
) -> Result<(), PersistCacheError> {
self.persist(&self.gh_notification_filter_option_file(), options.borrow())
}

self.fs.create_dir_all(self.dir.as_path())?;
fn persist<T>(&self, path: &Path, entry: &T) -> Result<(), PersistCacheError>
where
T: ?Sized + Serialize,
{
if let Some(parent) = path.parent() {
self.fs
.create_dir_all(parent)
.map_err(|err| PersistCacheError::Io {
path: parent.to_path_buf(),
io: err,
})?;
}

let mut file = self.fs.create_file(path)?;
self.fs
.create_file(path)
.map_err(|err| PersistCacheError::Io {
path: path.to_path_buf(),
io: err,
})
.and_then(|mut file| {
serde_json::to_writer(&mut file, entry).map_err(PersistCacheError::Serialize)
})
}

serde_json::to_writer(&mut file, options).map_err(anyhow::Error::from)
/// Load credential from filesystem.
/// This is blocking operation.
pub fn load_credential(&self) -> Result<Unverified<Credential>, LoadCacheError> {
self.load::<Credential>(&self.credential_file())
.map(Unverified::from)
}

pub(crate) fn load_gh_notification_filter_options(
&self,
) -> anyhow::Result<GhNotificationFilterOptions> {
let path = self.gh_notification_filter_option_file();
) -> Result<GhNotificationFilterOptions, LoadCacheError> {
self.load(&self.gh_notification_filter_option_file())
}

let mut file = self.fs.open_file(path)?;
fn load<T>(&self, path: &Path) -> Result<T, LoadCacheError>
where
T: DeserializeOwned,
{
self.fs
.open_file(path)
.map_err(|err| LoadCacheError::Io {
io: err,
path: path.to_path_buf(),
})
.and_then(|mut file| {
serde_json::from_reader::<_, T>(&mut file).map_err(LoadCacheError::Deserialize)
})
}

serde_json::from_reader::<_, GhNotificationFilterOptions>(&mut file)
.map_err(anyhow::Error::from)
fn credential_file(&self) -> PathBuf {
self.dir.join(config::cache::CREDENTIAL_FILE)
}

fn gh_notification_filter_option_file(&self) -> PathBuf {
Expand Down
2 changes: 1 addition & 1 deletion crates/synd_term/src/application/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ mod clock;
pub use clock::{Clock, SystemClock};

mod cache;
pub use cache::Cache;
pub use cache::{Cache, LoadCacheError, PersistCacheError};

mod builder;
pub use builder::ApplicationBuilder;
Expand Down
25 changes: 6 additions & 19 deletions crates/synd_term/src/auth/mod.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
use std::{
borrow::Borrow,
cmp::Ordering,
fmt, io,
fmt,
ops::{Deref, Sub},
path::PathBuf,
};

use chrono::{DateTime, Utc};
Expand All @@ -13,7 +12,7 @@ use thiserror::Error;
use tracing::debug;

use crate::{
application::{Cache, JwtService},
application::{Cache, JwtService, LoadCacheError, PersistCacheError},
config,
types::Time,
};
Expand All @@ -32,26 +31,14 @@ pub enum CredentialError {
GoogleJwtExpired { refresh_token: String },
#[error("google jwt email not verified")]
GoogleJwtEmailNotVerified,
#[error("failed to open: {path} :{io_err}")]
Open {
#[source]
io_err: std::io::Error,
path: PathBuf,
},
#[error("serialize credential: {0}")]
Serialize(serde_json::Error),
#[error("deserialize credential: {0}")]
Deserialize(serde_json::Error),
#[error("decode jwt: {0}")]
DecodeJwt(JwtError),
#[error("refresh jwt id token: {0}")]
RefreshJwt(JwtError),
#[error("persist credential: {path} :{io_err}")]
PersistCredential {
#[source]
io_err: io::Error,
path: PathBuf,
},
#[error("persist credential: {0}")]
PersistCredential(#[from] PersistCacheError),
#[error("load credential: {0}")]
LoadCredential(#[from] LoadCacheError),
}

#[derive(Serialize, Deserialize, Clone, PartialEq, Eq)]
Expand Down

0 comments on commit e9445da

Please sign in to comment.