How to unwrap `Result` without macro/ Learning Rust


#1

Off-the-clock, I’m learning our native libraries and I want to get a better grasp of Rust while doing so.

When using create_acc, I want to learn how to properly unwrap the result of the operation using a match statement, rather than using the unwrap! macro.

Why? Education and understanding.

Currently, when I run:

extern crate safe_authenticator;
use safe_authenticator::{Authenticator, AuthError};

fn main() {
    let username = String::from("someusernamethatmeetsrequirements");
    let password = String::from("somepasswordthatmeetsrequirements");
    let invitation = String::from("someinvitation");

    let auth = match Authenticator::create_acc(username.into(), password.into(), invitation.into(), |_| ()) {
      Ok(Authenticator) => Authenticator,
      Err(AuthError) => AuthError,
    };

}
error[E0308]: match arms have incompatible types
  --> src\main.rs:20:16
   |
20 |       let auth = match Authenticator::create_acc(username.into(), password.into(), invitation.into(), |_| ()) {
   |  ________________^
21 | |       Ok(Authenticator) => Authenticator,
22 | |       Err(AuthError) => AuthError,
23 | |     };
   | |_____^ expected struct `safe_authenticator::Authenticator`, found enum `safe_authenticator::AuthError`
   |
   = note: expected type `safe_authenticator::Authenticator`
              found type `safe_authenticator::AuthError`
note: match arm with an incompatible type
  --> src\main.rs:22:25
   |
22 |       Err(AuthError) => AuthError,
   |                         ^^^^^^^^^

So, instead of Err(AuthError) => AuthError,, I’m wondering if it’s expecting, Err(AuthError) => Authenticator?

I try that and receive:

error[E0423]: expected value, found struct `Authenticator`
  --> src\main.rs:22:25
   |
22 |       Err(AuthError) => Authenticator,
   |                         ^^^^^^^^^^^^^ did you mean `Authenticator { /* fields */ }`?

I’m confused because now the compiler is telling me that it wants a value instead of a struct, like it was asking for in the previous error message.

Also, what’s the best way to log values. In javascript, I throw console.log in everywhere to learn about values. Do I need to make my own custom version of the library that implements Display and Debug so that I can use println!?

Thank you for your help.


#2

The first error is because the first arm of your match statement returns a value of type Authenticator and the second arm returns a value of type AuthError. Both values are potentially stored in the same variable (auth) so the compiler cannot infer a type for this variable and complains about the type incompatibility.

Another problem is that a match pattern defines normally a variable name in snake_case but you use type name instead in CamelCase. This means you are shadowing type names with variable names.

This is the origin of the second error: in Err(AuthError) => Authenticator the pattern defines AuthError variable, but in the body of the arm you use Authenticator which is not shadowed anymore and is a type name again, hence the error about usage of a struct instead of a value.

Maybe what you want is something like:

let auth = match Authenticator::create_acc(username.into(), password.into(), invitation.into(), |_| ()) {
    Ok(authenticator) => authenticator,
    Err(auth_error) => {
        panic!("Authentication error: {:?}", auth_error)
    }
};

(untested)

About logging, macros of log crate should be used: error!, warn!, info!, debug! and trace!. These macros define an API and IMO its best implementation is given by maidsafe_utilities crate.


#3

Thank you for the education and the code example, it worked.

I had to change my use of .clone method instead of .into method because the compiler couldn’t infer the argument type.

let auth = match Authenticator::create_acc(username.clone(), password.clone(), invitation.clone(), |_| ()) {
      Ok(authenticator) => authenticator,
      Err(auth_error) => {
        panic!("Authentication error: {:?}", auth_error)
      },
    };

I have a lot to learn but it’s worth it.

Thank you.


#4