Function to return multiple types

I've searched for hours but can't find the solution to this so apologies if this is covered somewhere else.

I'm a rust newbie and I'm trying to create a helper function to return structs based on a string input but I can't figure out a way to return multiple types as part of a Result return type.

Simple example of this is here where WorkerA and WorkerB are just structs with some arbitrary methods.

use workers::{WorkerA, WorkerB};


async fn launch_worker(worker_type: &str)-> Result< <WorkerA, WorkerB> , Box<dyn Error>>{
    match worker_type{
        "WorkerA" => WorkerA::new(),
        "WorkerB" => WorkerB::new(),
        _ => panic!("worker type not found")
    }
}

What I've written here doesn't work and is more aspirational, what I'm looking to understand is, is this possible or does the compiler have to know there's only one possible return types. I've tried generics but to no luck.

Any help would be greatly appreciated! Many thanks!

Every function needs to have a return type known at compile time, but there are a couple of ways to unify several types into one. The simplest is an enum:

pub enum AorB {
    A(WorkerA),
    B(WorkerB)
}

async fn launch_worker(worker_type: &str)-> Result<AorB, Box<dyn Error>>{
    match worker_type {
        "WorkerA" => Ok(AorB::A(WorkerA::new())),
        "WorkerB" => Ok(AorB::B(WorkerB::new())),
        _ => panic!("worker type not found")
    }
}

An alternative is to return a boxed trait object, which requires both structs to implement the same trait (eg. Worker):

async fn launch_worker(worker_type: &str)-> Result<Box<dyn Worker>, Box<dyn Error>>{
    match worker_type {
        "WorkerA" => Ok(Box::new(WorkerA::new()) as Box<dyn Worker>),
        "WorkerB" => Ok(Box::new(WorkerB::new()) as Box<dyn Worker>),
        _ => panic!("worker type not found")
    }
}

Thanks this is really helpful!

A follow up however: using a boxed trait is perfect for my use case as WorkerA and WorkerB will both implement methods with the same names and return types. But when I use the launch worker function after awaiting it and unwrapping the result I get the type 'Box < dyn Worker>' which I can't access any of WorkerA or WorkerB's methods from.

e.g.

let some_worker = launch_worker(&"WorkerA").await.unwrap();
let some_value = some_worker.some_method();

doing the above gives me "method not found in Box<dyn Worker>".

How can I access the methods?

Did you put those methods on the trait?

I hadn't but that makes sense, thanks so much! :slight_smile:

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.