-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(data_storage): implement DataStorage for playlist count management
- Loading branch information
1 parent
f984d38
commit a0b8a0c
Showing
10 changed files
with
171 additions
and
6 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
use std::fs; | ||
|
||
use directories::BaseDirs; | ||
use serde::Deserialize; | ||
use serde::Serialize; | ||
|
||
use crate::utils::data_file::DataFile; | ||
|
||
/// Storage for data other than configurations | ||
#[derive(Serialize, Deserialize)] | ||
pub struct DataStorage { | ||
playlist_count: u64, | ||
} | ||
|
||
impl DataStorage { | ||
/// Increment the playlist count, returning the old count for usage | ||
pub fn incr_playlist_count(&mut self) -> u64 { | ||
let count = self.playlist_count; | ||
self.playlist_count += 1; | ||
count | ||
} | ||
} | ||
|
||
impl Default for DataStorage { | ||
fn default() -> Self { | ||
Self { playlist_count: 1 } | ||
} | ||
} | ||
|
||
impl DataFile for DataStorage { | ||
fn path() -> std::path::PathBuf { | ||
let mut path = BaseDirs::new() | ||
.expect("Couldn't find standard directory. Is your system an oddball one?") | ||
.data_local_dir() | ||
.to_path_buf(); | ||
path.push("alistral"); | ||
fs::create_dir_all(&path).expect("Couldn't create config directory"); | ||
path.push("data_storage.txt"); | ||
path | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
use core::ops::Deref; | ||
use core::ops::DerefMut; | ||
use std::sync::RwLock; | ||
use std::sync::RwLockReadGuard; | ||
use std::sync::RwLockWriteGuard; | ||
use std::thread::panicking; | ||
|
||
use super::DataFile; | ||
|
||
pub struct FileGuard<T: DataFile>(RwLock<T>); | ||
|
||
impl<T: DataFile> FileGuard<T> { | ||
pub fn new(config: T) -> Self { | ||
Self(RwLock::new(config)) | ||
} | ||
|
||
pub fn read( | ||
&self, | ||
) -> Result<RwLockReadGuard<'_, T>, std::sync::PoisonError<std::sync::RwLockReadGuard<'_, T>>> | ||
{ | ||
self.0.read() | ||
} | ||
|
||
pub fn read_or_panic(&self) -> RwLockReadGuard<'_, T> { | ||
self.read().expect("Lock poisoned") | ||
} | ||
|
||
pub fn write( | ||
&self, | ||
) -> Result<FileWriteGuard<'_, T>, std::sync::PoisonError<std::sync::RwLockWriteGuard<'_, T>>> | ||
{ | ||
self.0.write().map(|guard| FileWriteGuard(guard)) | ||
} | ||
|
||
pub fn write_or_panic(&self) -> FileWriteGuard<'_, T> { | ||
self.write().expect("Lock poisoned") | ||
} | ||
} | ||
|
||
pub struct FileWriteGuard<'l, T: DataFile>(RwLockWriteGuard<'l, T>); | ||
|
||
impl<'l, T: DataFile> Deref for FileWriteGuard<'l, T> { | ||
type Target = RwLockWriteGuard<'l, T>; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
&self.0 | ||
} | ||
} | ||
|
||
impl<T: DataFile> DerefMut for FileWriteGuard<'_, T> { | ||
fn deref_mut(&mut self) -> &mut Self::Target { | ||
&mut self.0 | ||
} | ||
} | ||
|
||
impl<T: DataFile> Drop for FileWriteGuard<'_, T> { | ||
fn drop(&mut self) { | ||
if panicking() { | ||
return; | ||
} | ||
|
||
self.0.save().unwrap(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
use std::fs::File; | ||
use std::io; | ||
use std::path::PathBuf; | ||
|
||
use file_guard::FileGuard; | ||
use serde::de::DeserializeOwned; | ||
use serde::Serialize; | ||
|
||
pub mod file_guard; | ||
|
||
pub trait DataFile: Serialize + DeserializeOwned + Default { | ||
fn path() -> PathBuf; | ||
|
||
fn load_unguarded() -> Result<Self, crate::Error> { | ||
match File::open(Self::path().as_path()) { | ||
Ok(data) => { | ||
serde_json::from_reader(data).map_err(crate::Error::ConfigLoadDeserializationError) | ||
} | ||
Err(err) => { | ||
if err.kind() == io::ErrorKind::NotFound { | ||
Ok(Self::default()) | ||
} else { | ||
Err(crate::Error::ConfigLoadError(err)) | ||
} | ||
} | ||
} | ||
} | ||
|
||
fn load() -> Result<FileGuard<Self>, crate::Error> { | ||
Ok(FileGuard::new(Self::load_unguarded()?)) | ||
} | ||
|
||
fn save(&self) -> Result<(), crate::Error> { | ||
let file: File = | ||
File::create(Self::path().as_path()).map_err(crate::Error::ConfigFileCreationError)?; | ||
serde_json::to_writer_pretty(file, self).map_err(crate::Error::ConfigFileWriteError)?; | ||
Ok(()) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.