Apologies for the business logic clutter in my code examples below but I figured to leave it because it actually might help people give input on what I'm trying to accomplish besides my main question:
- The
FileDatabase
struct is supposed to hold avec
of structs that implement theFileDatabaseEntity
trait - I'm struggling to make that happen since I can't specify the generic params when declaring the vec on the
FileDatabase
field level - As I understand it (vaguely) , this is where "type erasure" is a solution
- My main problem is an error, in the
init_db
function, where I build thecolumn_family_descriptors
thename()
function can't be called, I have the following error:
the trait bound `(dyn std::any::Any + 'static): ancestors_cache_entry::_::_serde::Deserialize<'_>` is not satisfied
for local types consider adding `#[derive(serde::Deserialize)]` to your `(dyn std::any::Any + 'static)` type
Below is the rest of the code:
use serde::{de::DeserializeOwned, Serialize};
use std::{any::Any, path::PathBuf, sync::Arc};
use rocksdb::{ColumnFamilyDescriptor, DBCompressionType, Options, DB};
pub trait FileDatabaseEntity {
type Key: Serialize + DeserializeOwned;
type Value: Serialize + DeserializeOwned;
fn name(&self) -> &str;
fn serialize(&self, value: &Self::Value) -> anyhow::Result<Vec<u8>> {
Ok(bincode::serialize(value)?)
}
fn deserialize(&self, value: &[u8]) -> anyhow::Result<Self::Value> {
Ok(bincode::deserialize(value)?)
}
fn create(&self, key: &Self::Key, value: &Self::Value) -> anyhow::Result<()>;
fn read(&self, key: &Self::Key) -> anyhow::Result<Self::Value>;
fn update(&self, key: &Self::Key, value: &Self::Value) -> anyhow::Result<()>;
fn delete(&self, key: &Self::Key) -> anyhow::Result<()>;
}
pub type FileDatabaseEntityErased =
Box<dyn FileDatabaseEntity<Key = Box<dyn Any>, Value = Box<dyn Any>>>;
pub struct FileDatabase {
pub path: PathBuf,
pub entities: Vec<FileDatabaseEntityErased>,
pub db: Option<Arc<DB>>,
}
impl FileDatabase {
pub fn new(path: PathBuf) -> Self {
Self {
path,
entities: vec![],
db: None,
}
}
pub fn add_entity(&mut self, entity: FileDatabaseEntityErased) {
self.entities.push(entity);
}
pub fn init_db(&self) {
let mut opts = Options::default();
let mut cf_opts = Options::default();
opts.set_compression_type(DBCompressionType::Lz4);
cf_opts.set_compression_type(DBCompressionType::Lz4);
let column_family_descriptors = self
.entities
.iter()
.map(|entity| {
let entity_name = entity.name(); // Not possible, how do I do this?
ColumnFamilyDescriptor::new(entity_name, cf_opts.clone())
})
.collect::<Vec<_>>();
opts.create_if_missing(true);
opts.create_missing_column_families(true);
let db = DB::open_cf_descriptors(&opts, self.path.clone(), column_family_descriptors)?;
self.db = Some(Arc::new(db));
}
}