0

I would like to create a Command DP with a command which cannot be known at compile time, but i don't know how to make it well.

The minimal code reproduction

use std::path::{Path, PathBuf};
use std::process::exit;

trait Command {
    fn execute<P: AsRef<Path>>(&self, path: P) -> bool
    where
        Self: Sized,
    {
        false
    }
}

struct RenameCommand;

impl RenameCommand {
    pub fn new() -> Self {
        RenameCommand {}
    }
}

impl Command for RenameCommand {
    fn execute<P: AsRef<Path>>(&self, path: P) -> bool {
        false
    }
}

struct CopyCommand;

impl CopyCommand {
    pub fn new() -> Self {
        CopyCommand {}
    }
}

impl Command for CopyCommand {
    fn execute<P: AsRef<Path>>(&self, path: P) -> bool {
        false
    }
}

fn execute_commmand<P: AsRef<Path>>(command: &Box<dyn Command>, path: P) -> bool {
    command.execute(path)
}

fn main() {
    let origin_file_path = PathBuf::from("/bin");

    let command: Box<dyn Command> = match "rename" {
        "rename" => Box::new(RenameCommand),
        "copy" => Box::new(CopyCommand),
        _ => {
            eprintln!("Error");
            exit(1);
        }
    };

    for _ in 0..10{
      // Some code
      // I would like to do something like
      // error: the `execute` method cannot be invoked on a trait object
      command.execute(origin_file_path);
      // Or if needed
      execute_commmand(&command, origin_file_path);
    }

}

I used Box to create the struct at runtime but I don't know how to run a method on this boxed struct.

command.execute(data); /// doesn't work

so i tried to create a function like

execute_command<P: AsRef<Path>>(command: &Box(dyn Command), path: P) -> bool{
    command.execute(path)
}

But i got this error: the execute method cannot be invoked on a trait object.

Ectaclick
  • 5
  • 2
  • 2
    Please put the [mre] here as text in a code block instead of just linking to it, links go dead or get invalid. And people reading this should not be required to click a link to understand the question. Also please paste the full error message rather than an exceprt. – cafce25 Dec 27 '22 at 15:47
  • You can't with a generic function or one restricted to `Self: Sized`, see [Why does a generic method inside a trait require trait object to be sized?](https://stackoverflow.com/questions/42620022/why-does-a-generic-method-inside-a-trait-require-trait-object-to-be-sized) – cafce25 Dec 27 '22 at 15:55
  • 1
    Nitpick: Don't take `&Box`, take `&dyn Command` instead. See [Why is it discouraged to accept a reference to a String (&String), Vec (&Vec), or Box (&Box) as a function argument?](https://stackoverflow.com/questions/40006219/why-is-it-discouraged-to-accept-a-reference-to-a-string-string-vec-vec-o). – Chayim Friedman Dec 27 '22 at 16:28
  • Ok i change my method definition and it's works now, but i would like to understand why a generic function cannot be invoked on trait object ? Is it because the size cannot be known at compile time ? – Ectaclick Jan 02 '23 at 19:29

0 Answers0