Search code examples
tauri

How do you properly move the handle of a method into a module?


Questions

I'm new to Rust

  1. I'm trying to understand how do you move the handle (closure) of a method into a module (separate file) in order to split large chunks of code into something manageable? In particular, in the code below, I want to move the handle of .on_system_tray_event() method into the system_tray module.

  2. Did I move the handle of .system_tray() method into the system_tray module correctly or is there a better way to do this?

Code

src/main.rs

use tauri::{SystemTrayEvent, Manager};

mod system_tray;

fn main() {
  tauri::Builder::default()
    .system_tray(system_tray::get_system_tray())
    .on_system_tray_event(|app, event| match event {
      SystemTrayEvent::LeftClick {
        position: _,
        size: _,
        ..
      } => {
        println!("system tray received a left click");
      }
      SystemTrayEvent::RightClick {
        position: _,
        size: _,
        ..
      } => {
        println!("system tray received a right click");
      }
      SystemTrayEvent::DoubleClick {
        position: _,
        size: _,
        ..
      } => {
        println!("system tray received a double click");
      }
      SystemTrayEvent::MenuItemClick { id, .. } => {
        match id.as_str() {
          "quit" => {
            std::process::exit(0);
          }
          "hide" => {
            let window = app.get_window("main").unwrap();
            window.hide().unwrap();
          }
          _ => {}
        }
      }
      _ => {}
    })
    .run(tauri::generate_context!())
    .expect("error while running tauri application");
}

src/system_tray.rs

use tauri::{SystemTray, CustomMenuItem, SystemTrayMenu, SystemTrayMenuItem};

pub fn get_system_tray () -> SystemTray {
  let quit = CustomMenuItem::new("quit".to_string(), "Quit");
  let hide = CustomMenuItem::new("hide".to_string(), "Hide");
  let tray_menu = SystemTrayMenu::new()
    .add_item(quit)
    .add_native_item(SystemTrayMenuItem::Separator)
    .add_item(hide);
  
  let system_tray = SystemTray::new().with_menu(tray_menu);
  return system_tray
}

pub on_system_tray_event_handler () {
  ...
}

Solution

  • The handle in on_system_tray_event is just a closure. So just cut and paste everything after |app, event| into its own function, then call that function. Short and sweet:

    some_function.some_handle_stuff(|x, y| A_BIG_BLOCK_FO_CODE);
    

    becomes

    some_function.some_handle_stuff(|x, y| a_function(x, y));
    
    fn a_function(x: some_type, y: another_type) {
      A_BIG_BLOCK_OF_CODE
    }
    

    Now just make sure the argument types and return types make sense and you're good to go. Then as a next step you can move that function into a different module.

    EDIT: Note, this doesn't work if the BIG_BLOCK_OF_CODE for the closure "captures the environment". On quick glance, that doesn't seem to be the case here. Otherwise you'll need to add the salient parts of the environment to the function arguments.