Need help invoking a rust library with Typescript in Tauri

294 Views Asked by At

In my project I want to analyze the source code of a PHP file and convert it to AST. There is already a javascript package for this, but it only works with node. So I tried to convert the PHP code to AST using a Rust library. However, I have no experience with Rust and do not get anywhere:

inside file src-tauri/src/main.rs:

#[tauri::command]
fn php_to_ast(code: &str) -> String {
    match parser::parse(code) {
        Ok(ast) => {
            format!("{:?}", ast)
        }
    }
}

invoke in typescript:

invoke('php_to_ast', { code: value }).then((result) => {
            this._ast = result;
            console.log({ast: this._ast});
        }).catch((error) => {
            console.error({error});
        });

the console error message is:

error[E0004]: non-exhaustive patterns: `Err(_)` not covered
 --> src/main.rs:8:11
  |
8 |     match parser::parse(code) {
  |           ^^^^^^^^^^^^^^^^^^^ pattern `Err(_)` not covered
  |
note: `Result<Vec<php_parser_rs::parser::ast::Statement>, ParseErrorStack>` defined here
  = note: the matched value is of type `Result<Vec<php_parser_rs::parser::ast::Statement>, ParseErrorStack>`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
  |
11~         }
12+         Err(_) => todo!()
  |

I am aware that I am not fully processing the return values from parser::parse(). For comparison, in the Rust library example, the call looks like this:

fn main() -> Result<()> {
    match parser::parse(CODE) {
        Ok(ast) => {
            println!("{:#?}", ast);
        }
        Err(err) => {
            println!("{}", err.report(CODE, None, true, false)?);

            println!("parsed so far: {:#?}", err.partial);
        }
    }

    Ok(())
}

Presumably I should also still process and return the errors (as a string with an error message?).

1

There are 1 best solutions below

0
Matrix4f On

In rust, match statements need to be "exhaustive". This means that every possible "arm" has to be covered. If you want to handle errors in your rust code, you can add the Err(e) arm to your match expression.

match parser::parse(code) {
  Ok(ast) => format!("{:?}", ast);
  Err(error) => /* Handle Error in Rust and return some indicator String */;
}

And in your typescript code you can then check for that returned error string:

invoke("php_to_ast", { code: value })
  .then((ast_or_error) => {
    if (ast_or_error == "your_indicator") {
      /* Handle error in typescript */
    } else {
      /* Use your ast */
    }
  })