Jakob Nielsen
Jakob Nielsen

Reputation: 5198

Rust impl Trait as function return type

I have the following function in which Command is a trait

pub fn parse_arguments(matches: ArgMatches) -> Result<impl Command, &'static str>

Inside the function body, I want to return different implementations of Command depending on the arguments like

match args.subcommand() {
    ("init", Some(args)) => {
        Ok(Init::new(args))
    }
    ("btc", Some(args)) => {
        Ok(ImportBtc::new(args))
    },
    ("grin", Some(args)) => {
        Ok(ImportGrin::new(args))
    },
    _ => Err ("Invalid subcommand supplied")
}

Compilation will fail with an error:

expected struct `commands::cmd_types::Init`, found struct `commands::cmd_types::ImportBtc`

and similar for the ImportGrin return line.

Have I misunderstood how impl Trait works?

Upvotes: 6

Views: 3455

Answers (1)

Daniel Wagner-Hall
Daniel Wagner-Hall

Reputation: 2596

Unfortunately this isn't quite what impl Trait does. impl Trait as a return type means "This function will return a single type which implements this trait", whereas you're trying to return multiple types which implement the trait. This is hard for the compiler because it needs to know how big the type being returned is, and different types have different sizes.

Some options:

  1. Box the return values, because a Box always has the same size
  2. Define an enum which has a variant per return type, wrap your return values in the enum, and implement the trait for the enum.
  3. Use https://crates.io/crates/auto_enums which automates the enum creation described in 2.

Upvotes: 8

Related Questions