Replace `if let` syntax

Those are good news.

The thing is one needs to capture the second variant of the data, due there is many functions that returns a Result or an Option, or even some libraries a Result<Option>. I mean sugars for match for dealing with monads.

Basically would be great being able to destructure as quickly and clean as possible the monads. I mean, to manage the possible errors or limits what returns a function, for proceeding to work with the data.

// this code is inside of a function, so have to use return if needed.

let Ok(data) = res else Err(e) { log(e); return Err("Custom err"); };

// And one starts working with data

let Ok(data) = res else Err(e) { log(e); default };

// And one starts working with data

.

One usually also wants to try a second way for assigning the data:

let Ok(data) = res else Err(e) { 

    res2 else Err(e2) {
              log(e, e2);
	      return Err("res and res2 failed"); 
   }
};

.

And sometimes things like this, trying to escape from match towers as much as possible:

let Ok(data2) = res else Err(e) { 

    match e {
       Errortypet1() =>
	   { 
			res2 else Err(e2){
				log(e, e2);
				return Err("failed res, tryed res2 and also failed"); 
			}
	   },
       Errortypet4() =>
	   { 
			opt2 else None {
				log(e, "none");
				return Err("res and opt failed"); 
			}
	   },
	   _ =>{ log("unknown error"); return Err("unknown error"); }
   }
};

// And one starts working with data

I would use the following code pattern for that:

fn handle_input(input: Input) -> Result<(), CustomError> {
    let data = parse_data(input)?;

    // with default:
    let data = parse_data(input)
        .map_err(|e| { log(e); default })
        .into_ok_or_err();
}

fn parse_data(input: Input) -> Result<Data, ParseError> { /*...*/ }

impl From<ParseError> for CustomError {
    fn from(e: ParseError) -> CustomError {
        log(e);
        CustomError::new("Custom err")
    }
}

Here I would use this:

let data = match res {
    Ok(data) => data,
    Err(e) => match res2 {
        Ok(data) => data,
        Err(e2) => {
            log(e);
            log(e2);
            return Err("res and res2 failed");
        }
    }
};

You can pattern match deeper into your types like this:

let Ok(data) = match res { 
    Ok(data) => data,
    Err(e@Errortypet1()) => match res2 {
        Ok(data) => data,
        Err(e2) => {
            log(e);
            log(e2);
            return Err("failed res, tryed res2 and also failed"); 
        }
    }
    Err(e@Errortypet4()) => match opt2 {
        // here one could use let-else
        Some(data) => data,
        None => {
            log(e, "none");
            return Err("res and opt failed"); 
        }
    },
    Err(_) => {
        log("unknown error");
        return Err("unknown error");
    }
};

1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.