Rust Tauri
Intro
As Rust is getting more traction and more people want to learn it, I've decided to create another tutorial mainly for beginners. There are few ways to create desktop applications using Rust and Tauri is definitely one that will allow you to make beautiful UI (HTML/JS/CSS) and leverage power of Rust in the background. As Tauri lets you choose any frontend framework (or none) I've created a simple template that use Svelte and Bootstrap (through Sveltestrap) to give developers a nice starting point. To demonstrate how to use it we will create simple password generator.
If lost, here you can find finished project: https://github.com/jbarszczewski/pass-gen-tutorial
Let's start!
Create project
Ok this step is super simple. All you have to do is run this command:
degit jbarszczewski/tauri-svelte-template pass-gen-tutorial
Alternatively you can go to https://github.com/jbarszczewski/tauri-svelte-template and click Use this template
button.
Quick overview of the project:
/src
contains front-end code with the main view defined inApp.svelte
file./src-tauri
here lives 'back-end' Rust code.README.md
provides basic instructions how to work with Tauri.
Add Rust command
Ok we want to create a simple command that will accept password length and return random string.
We will require one package to be added, rand
, that generates random numbers. Open src-tauri/Cargo.toml
and add rand = "0.8.0"
under dependencies. At this point run yarn
and thenyarn tauri dev
command (from the project main directory) to view the changes in 'real-time'.
Note: First build might take a while as it's building project from scratch.
Now open /src-tauri/src/commands.rs
file and replace the existing content with the following:
use rand::Rng;
static CHARS: [char; 70] = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's','t', 'u', 'v', 'w', 'x', 'y', 'z','A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S','T', 'U', 'V', 'W', 'X', 'Y', 'Z', '!','@','#','$','%','^','&','*'];
#[tauri::command]
fn generate_password(length: u32) -> String{
let mut rng = rand::thread_rng();
let mut result = String::new();
for _x in 0..length {
result.push(CHARS[rng.gen_range(0..70)]);
}
result
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn generates_string() {
let result = generate_password(8);
assert_eq!(result.len(), 8);
}
}
Now let's look what this code does:
- Import
rand
package. - Create array with characters that can be used for password generation.
- Define new Tauri command
generate_password
that accepts password length as an integer. - Create new random generator and an empty string.
- In the 'for' loop fill the string with characters from
CHARS
array - Return string containing password.
Additionally we have a single test that checks if newly created password have proper length (run cargo test
from /src-tauri
directory). Of course there is a room for improvement, like adding options to select types of characters to be used (only lowercase, no symbols etc.) and expand tests for better coverage. But as mentioned at the beginning this is just a simple app to demonstrate the template.
Last thing to do is rename command imported in main.rs
to generate_password
rather than standard my_custom_command
and Rust code is ready to be used!
Modify Svelte component
We need to modify the front-end Svelte component to call our new command. Changes here are actually simple: we want to modify input to be a slider and pass it's value as a string to invoked command (remember we've changed the default name). Open App.svelte
and let's start adding those changes.
In <script>
section replace code after imports with following one:
let input: string = '8';
let result: string = '';
const handleClick = async () => {
result = await invoke('generate_password', {
length: +input,
});
};
Difference are:
- Default value for
input
- Command and parameter names with casting string to number:
+input
The <main>
tag will also look very similar, we update texts and change input to be a range
type:
<Container>
<Card class="mb-3">
<CardHeader>
<CardTitle>Password Generator</CardTitle>
</CardHeader>
<CardBody>
<CardSubtitle>Generate random password</CardSubtitle>
<CardText>Press 'Generate' button to create password with length: {input}.</CardText>
<input
type="range"
id="exampleRange"
bind:value="{input}"
min="{1}"
max="{32}"
step="{1}"
/>
<button color="primary" on:click="{handleClick}">Generate</button>
</CardBody>
<CardFooter> {#if result.length !== 0} {result} {:else} No result yet. {/if} </CardFooter>
</Card>
</Container>
And we're done! Congratulations, you've just created your first Tauri app!
Conclusion
As you can see, it's really easy to create application with nice UI leveraging power of Rust in the background. There is a lot more good stuff in Tauri, like: updater if you plan to distribute your app and make sure users don't miss newest releases, splashscreen if app needs some time to load, etc. I really recommend heading to Tauri Docs to learn more about all the possibilities.
The complete project can be found here https://github.com/jbarszczewski/pass-gen-tutorial
I hope you've enjoyed this tutorial and as always if any suggestions/questions don't hesitate to leave a comment below.
Thanks for reading and till the next time!