You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: module_management.rs
    path of file: ./repos/rust_rpg_toolkit/src/gui/main_menu
    
    the code of the file until where you have to start completion: use crate::gui::*;

use crate::modules::{get_available_modules, ModuleParams, ACTIVE_MODULES_FILE_NAME};

#[derive(Debug, Copy, Clone)]
enum LoadOrderChange {
    LoadBefore { i: usize, target_i: usize },
    LoadAfter { i: usize, target_i: usize },
}

// Returns a modules index in the active_modules vector, calculated from either the entry
// id, or the id of the drop-zone before the entry, as well as a bool that will be true
// if the id was for the modules entry in the module list
fn id_to_module_index(id: u64) -> (usize, bool) {
    if id % 2 == 0 {
        ((id as usize / 2) - 1, true)
    } else {
        (((id as usize -
    
pub(crate) async fn show_module_management() {
    let gui_skins = storage::get::<GuiSkins>();
    root_ui().push_skin(&gui_skins.default);

    let mut will_require_restart = false;

    let mut should_save = false;
    let mut should_cancel = false;

    let size = vec2(500.0, 600.0);
    let position = get_centered_on_screen(size);

    let game_params = storage::get::<GameParams>();

    let available_modules = get_available_modules().unwrap();

    let active_modules_file_path =
        Path::new(&game_params.modules_path).join(ACTIVE_MODULES_FILE_NAME);
    let bytes = load_file(&active_modules_file_path).await.unwrap();
    let mut active_modules = serde_json::from_slice::<Vec<String>>(&bytes)
        .unwrap()
        .into_iter()
        .filter(|module| available_modules.contains_key(module))
        .collect::<Vec<String>>();

    let mut module_state: HashMap<String, bool> = HashMap::from_iter(
        available_modules
            .iter()
            .map(|(name, _)| (name.clone(), active_modules.contains(name))),
    );

    let mut is_dragging = false;
    let mut load_order_change = None;

    loop {
        widgets::Window::new(hash!(), position, size)
            .titlebar(false)
            .ui(&mut *root_ui(), |ui| {
                ui.push_skin(&gui_skins.header_label);
                ui.label(None, "Modules");
                ui.pop_skin();

                let size = vec2(450.0, 550.0);

                widgets::Group::new(hash!(), size)
                    .position(vec2(0.0, 48.0))
                    .ui(ui, |ui| {
                        let mut i = 0;
                        for name in &active_modules {
                            if let Some(module) = available_modules.get(name) {
                                let value = module_state.get_mut(name).unwrap();

                                match draw_module_entry(ui, i, name, module, value, is_dragging) {
                                    Drag::Dropped(_, Some(id)) => {
                                        is_dragging = false;

                                        let (target_i, is_entry) = id_to_module_index(id);
                                        load_order_change = if is_entry {
                                            Some(LoadOrderChange::LoadAfter { i, target_i })
                                        } else {
                                            Some(LoadOrderChange::LoadBefore { i, target_i })
                                        };
                                    }
                                    Drag::Dropped(_, _) => {
                                        is_dragging = false;
                                    }
                                    Drag::Dragging(_pos, _id) => {
                                        is_dragging = true;
                                    }
                                    _ => {}
                                }

                                i += 1;
                            }
                        }

                        for (name, module) in &available_modules {
                            if !active_modules.contains(name) {
                                let value = module_state.get_mut(name).unwrap();
                                draw_module_entry(ui, i, name, module, value, false);

                                i += 1;
                            }
                        }
                    });

                if will_require_restart {
                    ui.push_skin(&gui_skins.warning_label);
                    ui.label(vec2(0.0, 493.0), "Changes require a restart!");
                    ui.pop_skin();
                }

                let btn_size = vec2(222.0, 32.0);

                let save_btn = widgets::Button::new("Save")
                    .position(vec2(0.0, 520.0))
                    .size(btn_size)
                    .ui(ui);

                let cancel_btn = widgets::Button::new("Cancel")
                    .position(vec2(226.0, 520.0))
                    .size(btn_size)
                    .ui(ui);

                should_save = save_btn;
                should_cancel = cancel_btn;
            });

        if let Some(load_order_change) = load_order_change {
            match load_order_change {
                LoadOrderChange::LoadBefore { i, target_i } => {
                    let entry = active_modules.remove(i);

                    let target_i = if i < target_i { target_i - 1 } else { target_i };

                    active_modules.insert(target_i, entry);
                }
                LoadOrderChange::LoadAfter { i, target_i } => {
                    let entry = active_modules.remove(i);

                    let target_i = if i < target_i { target_i } else { target_i + 1 };

                    active_modules.insert(target_i, entry);
                }
            };

            will_require_restart = true;
        }

        load_order_change = None;

        active_modules.retain(|module| module_state.get(module).copied().unwrap_or_default());

        for (name, state) in &module_state {
            if *state && !active_modules.contains(name) {
                active_modules.push(name.clone());
                will_require_restart = true;
            }
        }

        if should_save || should_cancel {
            root_ui().pop_skin();

            #[cfg(not(any(target_os = "android", target_family = "wasm")))]
            if should_save {
                let json = serde_json::to_string_pretty(&active_modules).unwrap();
                fs::write(active_modules_file_path, &json).unwrap();
            }

            return;
        }

        end_frame().await;
    }
}