Search code examples
rustreturn-type

How to return a generic struct in Rust


Beginner in Rust, I'm wondering how to return generic data in a function.

pub fn tryparse() -> (CLIAction, ArgSingle) {
    let args = CLI::from_args();
    match args.cmd {
        SubCommand::Add(opt) => {
            (CLIAction::QuantityAdd,opt)
        }
        SubCommand::Del(opt) => {
            (CLIAction::QuantityDel,opt)
        }
    }
}

In this example both Add and Del get a ArgSingle struct type. However I'd like to implement a Search that would use a ArgSearch struct type, and return it... How to tell rust that tryparse() can return either ArgSingle or ArgSearch type?


Solution

  • Sounds like you want to return either ArgSingle or ArgSearch from tryparse() function. There are a few approaches to that, a common one is to use enumerations as the return.

    First, define an enum that represents all the possible types that can be returned from the function:

    
    enum CLIResult {
        Single(ArgSingle),
        Search(ArgSearch),
    }
    

    Then, modify the function to return this enum inside of the tuple:

    pub fn tryparse() -> (CLIAction, CLIResult) {
        let args = CLI::from_args();
        match args.cmd {
            SubCommand::Add(opt) => {
                (CLIAction::QuantityAdd, CLIResult::Single(opt))
            }
            SubCommand::Del(opt) => {
                (CLIAction::QuantityDel, CLIResult::Single(opt))
            }
            SubCommand::Search(opt) => {
                (CLIAction::Search, CLIResult::Search(opt))
            }
        }
    }
    

    Now, the function can return either ArgSingle as CLIResult::Single or ArgSearch as CLIResult::Search.

    To use the return value of tryparse(), you would need to pattern match on the CLIResult enum to extract the appropriate type of result. For example:

    let (action, result) = tryparse();
    match result {
        CLIResult::Single(single_arg) => {
            // Handle single argument case
        }
        CLIResult::Search(search_arg) => {
            // Handle search argument case
        }
    }