Embed Rust Functions in BubbleTea - LieutenantTeaTM/BubbleTea GitHub Wiki

In BubbleTea, due it it transpiling to native Rust, you can actually call Rust functions directly in BubbleTea, you just have to define them. It is important to keep in mind you can only deal with primitives when transferring data, and you must comply with the primitives BubbleTea uses. Rust uses many different sizes of primitives (i.e. i32, i64, etc.).

The current valid communicating types are:

BubbleTea Rust
int i64
float f64
str String
bool bool

However outside of these constraints you can run anything on Rust's backend.

Rust Setup

  1. Create an .rs file in your current BubbleTea transpiler directory. Keep note of the name, we'll need to link it to BubbleTea
  2. Set up a public (pub) function on Rust and write your code. Save it. Example:
pub fn say_hi() {
    println!("Hi!");
}

Linking Your Public Function to BubbleTea

  1. In the global scope add an extern function expression. These are defined as @!function_name <- "rust_file.rs"; The function name must match your rust function name, in my case it's say_hi. Do not add parenthesis or arguments. Use your Rust file name including the .rs. I named mine macro_utils.rs.

Your BubbleTea code should look something like this:

@!say_hi <- "macro_utils.rs";

fn main() -> null {
    
}

Now your function is linked! Run it and verify you are using the correct arguments and amount.

@!say_hi <- "macro_utils.rs";

fn main() -> null {
    say_hi();
}
Output:
Hi!

Passing arguments

Let's allow the user to add a name for our greeting function in Rust. I will update it as so:

pub fn say_hi(name: String) {
    println!("Hi!, {}", name);
}

Now in BubbleTea we have to pass the same amount of arguments and same type, in my case I'll add an inp!() input method so we can take a name in at runtime.

@!say_hi <- "macro_utils.rs";

fn main() -> null {
    say_hi(inp!());
}

Now if we run it we can enter a name and it will greet us!

Output:
Tea
Hi!, Tea

Returning data back to BubbleTea

As noted above verify you can communicate with BubbleTea with this type, otherwise it will crash.

For fun, let's make another function in Rust that reverses our name:

pub fn reverse_name(name: String) -> String {
    name.chars().rev().collect::<String>()
}

Now we need to link it to BubbleTea, we can do so with the same syntax just replacing the function name:

@!say_hi <- "macro_utils.rs";
@!reverse_name <- "macro_utils.rs";

I've went ahead and cleaned up the BubbleTea script so that it's a lot neater. Changes:

  • Linked the new Rust function
  • I've moved the name to it's own variable for re-use.
  • Used the new function on a str variable assignment
  • Added a PrintSingle "Your name reversed is: " for a nice note
  • Printed the reversed name from the function

Final Code: BubbleTea

@!say_hi <- "macro_utils.rs";
@!reverse_name <- "macro_utils.rs";

fn main() -> null {
    v name: str -> inp!();
    say_hi(name);

    v rev_name: str -> reverse_name(name);
    ps!("Your name reversed is: ");
    p!(rev_name);
}

Rust

pub fn say_hi(name: String) {
    println!("Hi!, {}", name);
}

pub fn reverse_name(name: String) -> String {
    name.chars().rev().collect::<String>()
}

Examples:

Output:
Tea
Hi!, Tea
Your name reversed is: aeT
Output:
John Smith
Hi!, John Smith
Your name reversed is: htimS nhoJ
⚠️ **GitHub.com Fallback** ⚠️