Rust and QML Jos van den Oever
play along:
git clone
[email protected]:vandenoever/metadatadb.git cd metadatadb cargo build
Advantages of Rust ●
Fast like C and C++
●
Safer than anything –
Memory safety
–
Thread safety
●
Elegant syntax
●
Simple build system
●
Structured macrosh
●
https://doc.rust-lang.org
This talk ●
Hello World
●
Simple application: metadatadb
●
500 LOC
●
Index and search file metadata
●
QML GUI
Our goal today
Our goal today Thread 1
QML UI
Searcher
main()
Thread 2
Thread 3
Sqlite
inotify
MetaDataDb
WalkDir
Hello World C++
Rust
#include
use std::env;
int main(int argc, char** argv) { std::cout result.filename.clone(), None => String::from("") } }
Connecting to Qt ●
A few experimental projects connect Qt to Rust
●
Our choice today: qmlrs, simple bindings to QML
●
Connect Rust structures to QML
Q_OBJECT Q_OBJECT! { Searcher: slot fn search(String, i64, i64); slot fn get_filename(i64); slot fn get_size(i64); slot fn get_mtime(i64); slot fn get_dir(i64); }
Initialize and start QML extern crate qmlrs;
fn ui(mdb: MetaDataDb) -> Result { let mut searcher = Searcher{ mdb: mdb, query: String::new(), sort_column: 0, sort_order: 0, results: Vec::new() }; let mut engine = qmlrs::Engine::new(); engine.set_property("searcher", searcher); engine.load_local_file("ui/search_ui.qml"); engine.exec(); Ok(()) }
const vs mut fn main() { let a = 3; a = 4; print!("{}", a); }
const vs mut fn main() { let a = 3; a = 4; print!("{}", a); } $ rustc change.rs change.rs:3:5: 3:10 error: re-assignment of immutable variable `a` [E0384] change.rs:3
a = 4; ^~~~~
change.rs:3:5: 3:10 help: run `rustc --explain E0384` to see a detailed explanation change.rs:2:9: 2:10 note: prior assignment occurs here change.rs:2
let a = 3; ^
error: aborting due to previous error
const vs mut fn main() { let mut a = 3; a = 4; print!("{}", a); }
Ownership fn print(a: String) { print!("{}", a); } fn main() { let a = String::from("Hello"); print(a); print(a); } $ rustc steal.rs steal.rs:7:11: 7:12 error: use of moved value: `a` [E0382] steal.rs:7
print(a); ^
steal.rs:7:11: 7:12 help: run `rustc --explain E0382` to see a detailed explanation steal.rs:6:11: 6:12 note: `a` moved here because it has type `collections::string::String`, which is non-copyable steal.rs:6
print(a); ^
error: aborting due to previous error
Ownership fn print(a: &String) { print!("{}", a); } fn main() { let a = String::from("Hello"); print(&a); print(&a); }
Ownership fn print(a: &String) { print!("{}", a); } fn main() { let a = String::from("Hello"); print(&a); print(&a); }
fn print(a: String) -> String { print!("{}", a); a } fn main() { let a = String::from("Hello"); b = print(a); print(b); }
Ownership fn print(a: &String) { print!("{}", a); } fn main() { let a = String::from("Hello"); print(&a); print(&a); }
fn print(a: String) { print!("{}", a); } fn main() { let a = String::from("Hello"); print(a.clone()); print(a); }
fn print(a: String) -> String { print!("{}", a); a } fn main() { let a = String::from("Hello"); b = print(a); print(b); }
Threading fn walk(path: String) -> Receiver { // Create a channel to receive the events. let (tx, rx) = sync_channel::(10000); thread::spawn(move || { for entry in WalkDir::new(path) { let entry = entry.unwrap(); let file_entry = to_file_entry(entry); if let Err(e) = tx.send(file_entry) { println!("{}", e); break; } } }); rx } fn print_dir_recursive(path: String) { let rx = walk(path); while let Ok(entry) = rx.recv() { print!("{}", entry); } }
Conclusions ●
Fast like C and C++
●
Safer than anything –
Memory safety
–
Thread safety
●
Elegant syntax
●
Simple build system
●
Structured macrosh
●
https://doc.rust-lang.org
unsafe { Questions? }
Hack Without Fear