Callback hell syntax

Hi,

I have some code that looks like this:

pub fn model(req: HttpRequest) -> HttpResponse {
    match req.match_info().get("foo") {
        Some(foo) => match req.match_info().get("bar") {
            Some(bar) => {
                match serde_json::to_string(&Foo { info : String::from("hello") }) {
                    Ok(body) => HttpResponse::Ok().body(body),
                    Err(err) => HttpResponse::InternalServerError().body(format!("Unable to serialize payload: {}", err))
                }
            },
            None => HttpResponse::BadRequest().body("Missing bar request param")
        },
        None => HttpResponse::BadRequest().body("Missing foo request param")
    }
}

Wonder if there are any idioms in Rust to take care of this “callback hell” syntax?

The two usual options are:

  1. embracing early returns:
pub fn model(req: HttpRequest) -> HttpResponse {
    let foo = match req.match_info().get("foo") {
        Some(it) => it,
        None => return HttpResponse::BadRequest().body("Missing foo request param"),
    };
    let bar = match req.match_info().get("bar") {
        Some(it) => it,
        None => return HttpResponse::BadRequest().body("Missing bar request param"),
    };
    let body = match serde_json::to_string(&Foo { info : String::from("hello") }) {
        Ok(it) => it,
        Err(err) => return  HttpResponse::InternalServerError().body(format!("Unable to serialize payload: {}", err)),
    };
    HttpResponse::Ok().body(body)
}
  1. modifying signatures to leverage ? operator
pub fn model(req: HttpRequest) -> Result<HttpResponse, HttpResponse> {
    let foo = req.match_info().get("foo")
        .ok_or_else(|| HttpResponse::BadRequest().body("Missing foo request param"))?;
    let bar = req.match_info().get("bar")
        .ok_or_else(|| HttpResponse::BadRequest().body("Missing bar request param"))?;
    let body = serde_json::to_string(&Foo { info : String::from("hello") })
        .map_err(|err| HttpResponse::InternalServerError().body(format!("Unable to serialize payload: {}", err)))?;
    Ok((HttpResponse::Ok().body(body)))
}
8 Likes