Struggling to implement parent with field of trait with associated types

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 a vec of structs that implement the FileDatabaseEntity 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 the column_family_descriptors the name() 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));
    }
}

Is this question still open?

I think the root of the problem is that you need to decide between compile-time and run-time polymorphism, i.e. generics or dyn. Deserialization with runtime polymorphism would require an "abstract factory" to construct the deserialized objects, with Any there is no way to know what to construct.

You didn't say why you can't make FileDatabase generic over the entity type.