Generic json database backend

This commit is contained in:
Wojciech Kozlowski 2023-04-13 15:04:28 +02:00
parent ea736cebed
commit 23d4aba09f
5 changed files with 23 additions and 27 deletions

View File

@ -94,6 +94,7 @@ mod tests {
use mockall::predicate;
use crate::{
collection::Collection,
database::{self, MockDatabase},
library::{self, MockLibrary, Query},
tests::COLLECTION,
@ -122,7 +123,7 @@ mod tests {
.expect_write()
.with(predicate::eq(database_input))
.times(1)
.return_once(|_| database_result);
.return_once(|_: &Collection| database_result);
let mut collection_manager = MhCollectionManager::new(library, database);
@ -164,7 +165,7 @@ mod tests {
database
.expect_write()
.times(1)
.return_once(|_| database_result);
.return_once(|_: &Collection| database_result);
let mut collection_manager = MhCollectionManager::new(library, database);

View File

@ -3,7 +3,8 @@
use std::fs;
use std::path::{Path, PathBuf};
use crate::collection::Collection;
use serde::de::DeserializeOwned;
use serde::Serialize;
#[cfg(test)]
use mockall::automock;
@ -27,25 +28,25 @@ pub trait JsonDatabaseBackend {
}
/// JSON database.
pub struct JsonDatabase {
backend: Box<dyn JsonDatabaseBackend + Send + Sync>,
pub struct JsonDatabase<JDB> {
backend: JDB,
}
impl JsonDatabase {
impl<JDB: JsonDatabaseBackend> JsonDatabase<JDB> {
/// Create a new JSON database with the provided backend, e.g. [`JsonDatabaseFileBackend`].
pub fn new(backend: Box<dyn JsonDatabaseBackend + Send + Sync>) -> Self {
pub fn new(backend: JDB) -> Self {
JsonDatabase { backend }
}
}
impl Database for JsonDatabase {
fn read(&self, collection: &mut Collection) -> Result<(), Error> {
impl<JDB: JsonDatabaseBackend> Database for JsonDatabase<JDB> {
fn read<D: DeserializeOwned>(&self, collection: &mut D) -> Result<(), Error> {
let serialized = self.backend.read()?;
*collection = serde_json::from_str(&serialized)?;
Ok(())
}
fn write(&mut self, collection: &Collection) -> Result<(), Error> {
fn write<S: Serialize>(&mut self, collection: &S) -> Result<(), Error> {
let serialized = serde_json::to_string(&collection)?;
self.backend.write(&serialized)?;
Ok(())
@ -162,9 +163,7 @@ mod tests {
.times(1)
.return_once(|_| Ok(()));
JsonDatabase::new(Box::new(backend))
.write(&write_data)
.unwrap();
JsonDatabase::new(backend).write(&write_data).unwrap();
}
#[test]
@ -176,9 +175,7 @@ mod tests {
backend.expect_read().times(1).return_once(|| result);
let mut read_data: Vec<Artist> = vec![];
JsonDatabase::new(Box::new(backend))
.read(&mut read_data)
.unwrap();
JsonDatabase::new(backend).read(&mut read_data).unwrap();
assert_eq!(read_data, expected);
}
@ -197,7 +194,7 @@ mod tests {
.return_once(|_| Ok(()));
backend.expect_read().times(1).return_once(|| result);
let mut database = JsonDatabase::new(Box::new(backend));
let mut database = JsonDatabase::new(backend);
let write_data = COLLECTION.to_owned();
let mut read_data: Vec<Artist> = vec![];

View File

@ -2,11 +2,11 @@
use std::fmt;
use serde::{de::DeserializeOwned, Serialize};
#[cfg(test)]
use mockall::automock;
use crate::collection::Collection;
pub mod json;
/// Error type for database calls.
@ -39,8 +39,8 @@ impl From<std::io::Error> for Error {
#[cfg_attr(test, automock)]
pub trait Database {
/// Read collection from the database.
fn read(&self, collection: &mut Collection) -> Result<(), Error>;
fn read<D: DeserializeOwned + 'static>(&self, collection: &mut D) -> Result<(), Error>;
/// Write collection to the database.
fn write(&mut self, collection: &Collection) -> Result<(), Error>;
fn write<S: Serialize + 'static>(&mut self, collection: &S) -> Result<(), Error>;
}

View File

@ -45,9 +45,7 @@ fn main() {
BeetsLibraryCommandExecutor::default().config(opt.beets_config_file_path.as_deref()),
);
let database = JsonDatabase::new(Box::new(JsonDatabaseFileBackend::new(
&opt.database_file_path,
)));
let database = JsonDatabase::new(JsonDatabaseFileBackend::new(&opt.database_file_path));
let collection_manager = MhCollectionManager::new(beets, database);

View File

@ -20,7 +20,7 @@ fn write() {
let file = NamedTempFile::new().unwrap();
let backend = JsonDatabaseFileBackend::new(file.path());
let mut database = JsonDatabase::new(Box::new(backend));
let mut database = JsonDatabase::new(backend);
let write_data = COLLECTION.to_owned();
database.write(&write_data).unwrap();
@ -34,7 +34,7 @@ fn write() {
#[test]
fn read() {
let backend = JsonDatabaseFileBackend::new(&*DATABASE_TEST_FILE);
let database = JsonDatabase::new(Box::new(backend));
let database = JsonDatabase::new(backend);
let mut read_data: Vec<Artist> = vec![];
database.read(&mut read_data).unwrap();
@ -48,7 +48,7 @@ fn reverse() {
let file = NamedTempFile::new().unwrap();
let backend = JsonDatabaseFileBackend::new(file.path());
let mut database = JsonDatabase::new(Box::new(backend));
let mut database = JsonDatabase::new(backend);
let write_data = COLLECTION.to_owned();
database.write(&write_data).unwrap();