vdswitcher 0.1.0

A simple tool to control virtual desktops on Windows 11
/*
    This file is part of VDSwitcher.
    The program's logic.

    Copyright (C) 2026 Ranosura

    VDSwitcher is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <https://www.gnu.org/licenses/>.

*/
use std::env;
use std::process;

use winvd;

use vdswitcher::{Flag, create_desktop, help_message, remove_desktop};

fn main() {
    let args: Vec<String> = env::args().collect();

    let flag = Flag::build(&args).unwrap_or_else(|err| {
        println!("Parsing error: {err}");
        process::exit(1)
    });

    if let Err(err) = run(flag) {
        println!("Application error: {err}");
        process::exit(2);
    }
}

pub fn run(flag: Flag) -> Result<(), &'static str> {
    match flag {
        Flag::CreaetDesktop(name) => create_desktop(&name),
        Flag::Help => {
            help_message();
            return Ok(());
        }
        Flag::ListDesktops => {
            let Ok(desktops) = winvd::get_desktops() else {
                return Err("error with retrieving virtual desktops");
            };

            let Ok(desktop_count) = winvd::get_desktop_count() else {
                return Err("error with retrieving the desktop count");
            };

            let width = desktop_count.ilog10() as usize;

            for (i, desktop) in desktops.iter().enumerate() {
                let Ok(name) = desktop.get_name() else {
                    return Err("error with retrieving a desktop name");
                };

                // get_name() returns nothing on an unnamed virtual desktop.
                // In this case, I shadow the empty name with a default placeholder.
                let name = if name.is_empty() {
                    format!("Desktop {}", i + 1)
                } else {
                    name
                };

                println!("{i:<width$} | {name}");
            }

            Ok(())
        }
        Flag::RemoveDesktop(i) => remove_desktop(i),
        Flag::SwithcDesktop(i) => {
            if winvd::switch_desktop(i).is_err() {
                return Err("the virtual desktop on the index does not exist");
            }

            Ok(())
        }
    }
}