Possible to write own version of `?` operator or some equivalent macro?


Firstly, am loving Rust so far!! I'm not advanced at all at programming, so I may be making some stupid mistakes/design choices. For this reason, let me explain my intent, in case I'm thinking about the problem wrong!

I am writing an API that interfaces with WASM (without wasm_bindgen) and so (at least for now) every communication has to be using i32s.

Frequently, my WASM facing functions accept as parameters id: i32, x: i32, y: i32 and turn those into custom data types Id and Point for use within my program.

I want every WASM facing function to return some kind of message (equivalent to Ok or Err) I'm going with 0 as i32 for Ok and -1 as i32 for Err. I don't know how I am going to deal with bool, but that's another matter.

Now, here's the problem:

fn get_id_point(id: i32, x: i32, y: i32) -> Result<(Id, Point), &'static str> {
        let id = Id::from(id)?;
        let point = Point::from(x, y)?;
        Ok((id, point))

// example function which uses get_id_point(), but eventually will be many functions
pub unsafe extern "C" fn place(id: i32, x: i32, y: i32) -> i32 {
    let (id, pos) = if let Ok((id, pos)) = get_id_point(id, x, y) {
        (id, pos)
    } else {
        return -1;
    // ... 
    0 // everything good, return 0

I will want every function to produce Id and Point variables (let (id, pos)), but I have 5 lines of boilerplate (and a helper function) for each function to do so.

Is there a better approach where with one line I either get the two variables or I return early with a -1?

Many thanks for your support!


macro_rules! int_try {
    ($value:expr) => {
        match $value {
            Ok(out) => out,
            Err(_) => return -1,

pub unsafe extern "C" fn place(id: i32, x: i32, y: i32) -> i32 {
    let (id, pos) = int_try!(get_id_point(id, x, y));

Damn Alice, you make programming look easy!

Thank you!

1 Like

The ? operator started life as the try!() macro, Welsh basically looked like this.