Is this possible in Rust?

pub struct Store<T> {
  data: RefCell<T>
}

impl <T> Store<T> {
  fn set(&mut self, x: T) {
    *self.data.borrow_mut() = x
  };
}

pub enum Foo<T, U> {
  Simple(Rc<Store<T>>),
  Complex(Fn(T) -> U, Rc<Store<U>>),
}

Now, is there a way to build this:

pub enum Magic<T> {
  Simple(Rc<Store<T>>),
  Complex [ exists some type U] (Fn(T) -> U, Rc<Store<U>>),
}

One hope why this is possible is that Rc<Store<U>> has size independent of U, and thus perhaps Foo<T, U> has size independent of U and we can just stuff it all into one struct.

EDIT:

Imagine we have a bunch of Foo<T, U1>, Foo<T, U2>, Foo<T, U3> and we want instead to stuff them all into a Vec<Magic<T>>

What do you need to be able to do with the values in Complex? You could define a trait that maps a T to an internal type and stores it, and then store a trait object of that trait in Complex. You won't be able to ever access a value of type U that way except by manual down casting though.

enum Foo<T> {
  Simple(Rc<Store<T>>),
  Complex(Box<dyn ComplexTrait<T>>),
}


struct Complex<F, U> {
    func: F,
    store: Rc<Store<U>>,
}

trait ComplexTrait<T> {
    fn set(&self, x: T);
}

impl<F, T, U> ComplexTrait<T> for Complex<F, U>
where
    F: Fn(T) -> U,
{
    fn set(&self, x: T) {
        let u = (self.func)(x);
        self.store.set(u);
    }
}
10 Likes

Valid point. So the XY problem here is that Store<T> is one end of a custom async Mailbox/Future implementation.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.