How to use Enumeration as the only Possible Error Values?

Viewed 103

Here's the error type that I wrote:

#[derive(Debug)]
pub struct AppErr {
    pub code: String,
    pub message: String,
}

I want AppErr to only have several possible values, so I use Enumeration

pub enum AppErrEnum {
    IncompatibleOS,
    FileNotFound,
    InvalidInput,
    UnknownErr,
}

I need to somehow convert AppErrEnum into AppErr type. So I use a function (convert_err()) such as this:

fn convert_err(val: AppErrEnum) -> AppErr {
    match val {
        AppErrEnum::IncompatibleOS => AppErr {
            code: String::from("INCOMPATIBLE_OS"),
            message: String::from("Sistem Operasi tidak didukung. Hanya support Windows Client."),
        },
        
        AppErrEnum::UnknownErr => AppErr {
            code: String::from("UNKNOWN_ERR"),
            message: String::from("Terjadi kesalahan yang tidak diketahui."),
        },

        // ..... other enum values here

    }
}

and I had to call the convert_err() in every instance of error

Err(convert_err(AppErrEnum::IncompatibleOS))

I found that this method is kinda ugly. I had to explicitly export the convert_err function and call it almost on every file.

Is there any way to automatically convert this enum type into AppErr so I can throw an error like this ? This is much simpler and easier to read for me:

Err(AppErrEnum::IncompatibleOS)
1 Answers

Implement the std::convert::From trait for implicit conversion

impl From<AppErrEnum> for AppErr {
    fn from(error: AppErrEnum) -> Self {
        match val {
            AppErrEnum::IncompatibleOS => AppErr {
                code: String::from("INCOMPATIBLE_OS"),
                message: String::from("Sistem Operasi tidak didukung. Hanya support Windows Client."),
            },
            
            AppErrEnum::UnknownErr => AppErr {
                code: String::from("UNKNOWN_ERR"),
                message: String::from("Terjadi kesalahan yang tidak diketahui."),
            },

            // ..... other enum values here

        }
    }
}

This can then be used as follows:

fn some_fn() -> Result<u32, AppErrEnum> { ... }

fn another_fn() -> Result<u32, AppErr> {
    some_fn()?
}

Related