Search code examples
rustserde-json

How to express variable type in match arm?


I'm trying to parse a piece of json string using serde_json in Rust. I want to match the result of the parse using the following syntax:

match serde_json::from_str(msg.to_text().unwrap()) {
    Ok(result) => {
        println!("Parsed: {}", response.text);
    }
    Err(error) => {
        println!("Failed to parse: {}", error);
    }
}

but the compiler complains to me that he doesn't know the type of the result and of course, he is right. But how can I tell him the type of the result? I tried the following code, but it didn't work either. So I want to express the type of variable in the match arm.

match serde_json::from_str(msg.to_text().unwrap()) {
    Ok(result: Response) => {
        println!("Parsed: {}", response.text);
    }
    Err(error) => {
        println!("Failed to parse: {}, {}", error, msg.to_text.unwrap());
    }
}

Solution

  • There's a few way you can specify the type. Either you can explicitly specify it using type parameters in the function call, i.e. by using this syntax func::<T>().

    match serde_json::from_str::<Response>(json) {
        Ok(response) => {}
        Err(err) => {}
    }
    

    Alternatively, you can assign the initial result to a variable, and hint the type there, i.e.

    let res: Result<Response, _> = serde_json::from_str(json);
    match res {
        Ok(response) => {}
        Err(err) => {}
    }
    

    or

    match serde_json::from_str(json) {
        Ok(response) => {
            let response: Response = response;
        }
        Err(err) => {}
    }
    

    Lastly you can also use @ bindings. However, this doesn't work if your type is an enum, as then you'd have to specify the exact variant you wanted.

    As in, if Response was an enum you could have multiple Ok(resp @ Response::???) match arms. But you couldn't have a single Ok(resp @ Response) match arm.

    match serde_json::from_str(json) {
        Ok(response @ Response { .. }) => {}
        Err(err) => {}
    }