Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trying to apply polymorphism with Box<_> has the error "cannot move a value ... the size cannot be statically determined"

Tags:

rust

I am applying the polymorphism solution in Rust to my problem. I would like to use this solution with Box<_> as it seems the most straight and simple, but it doesn't work.

#[derive(Clone, Copy)]
pub struct NewPost;

#[derive(Clone, Copy)]
pub struct Post;

#[derive(Clone, Copy)]
pub struct PgConnection;

#[derive(Clone, Copy)]
pub struct DBPost;

pub trait DBAdapter {
    fn create(self, post: NewPost) -> Post;
    fn read(self) -> Vec<Post>;
}

impl DBPost {
    // DATABASE classes
    pub fn establish_connection(self) -> PgConnection {
        unimplemented!()
    }
}

impl DBAdapter for DBPost {
    fn create(self, _post: NewPost) -> Post {
        unimplemented!()
    }

    fn read(self) -> Vec<Post> {
        unimplemented!()
    }
}

struct GetPostsCase {
    db: Box<dyn DBAdapter>,
}

impl GetPostsCase {
    pub fn new(db: Box<dyn DBAdapter>) -> GetPostsCase {
        GetPostsCase { db: db }
    }

    pub fn run(&self) -> Vec<Post> {
        let result = self.db.read();
        result
    }
}

The error is:

error[E0161]: cannot move a value of type dyn DBAdapter: the size of dyn DBAdapter cannot be statically determined
  --> src/lib.rs:45:22
   |
45 |         let result = self.db.read();
   |                      ^^^^^^^

error[E0507]: cannot move out of `*self.db` which is behind a shared reference
  --> src/lib.rs:45:22
   |
45 |         let result = self.db.read();
   |                      ^^^^^^^ move occurs because `*self.db` has type `dyn DBAdapter`, which does not implement the `Copy` trait
like image 209
carlos.baez Avatar asked Aug 26 '19 15:08

carlos.baez


1 Answers

Your read method takes the (unsized) value instead of taking a reference (whose size is always the same).

You can solve the problem by changing the contract of DBAdapter

from

fn read(self) -> Vec<Post> {

to

fn read(&self) -> Vec<Post> {
//      ^--- added the ampersand

(depending on your implementation you might need &mut)

like image 180
Denys Séguret Avatar answered Sep 17 '22 16:09

Denys Séguret