Anatomy of a Rust Program, Part VI: /src/wsl.rs

This blog post is the sixth in a series that describes the structure of the wink command line program that I have written in rust and that I use to invoke other Windows and Linux programs from bash and Windows shells under Windows Subsystem for Linux. This post describes a library named wsl that the wink program defines for features specific to Windows Subsystem for Linux, defined by the /src/wsl.rs file and hence the crate::wsl path.

Because this logic is not specific to the wink program, it could appear in a separate crate or even a separate project.

The wsl_path_or_self() method accepts a string slice and a Boolean indicating whether to convert that slice to Unix or Windows, and returns the value as a String. It uses a std::Process::Command to invoke the wslpath command (not available from cmd.exe, although cmd.exe can call bash.exe which can call wslpath) with arguments that control its output. If any error occurs, then it this function returns the value passed to it, as it was unable to convert that path.

The is_windows_or_wsl() function is true if is_windows() or is_wsl() returns true. The is_windows() function returns true if the wink command is running directly under windows rather than under WSL within Windows. The is_wsl() function returns true if the wink command is running under WSL, typically in a bash shell. The get_user_home() function returns the value of the USERPROFILE environment variable under Windows or the HOME environment variable under WSL. The get_user_home_default() function calls get_user_home() and returns its value or an empty string if the environment variable was not defined. The get_config_file_path() function uses get_user_home_default to construct a path to a configuration file that the wink command may use.

The /src/wsl.rs file also contains a tests module.

mod tests {
    #[test]
    fn get_user_home_default() {
        println!("wsl::tests::get_user_home_default()");
        //TODO:
    }

    #[test]
    fn it_converts_c_drive() {
        assert_eq!(
            &crate::wsl::wsl_path_or_self("C:\\", true /*unix*/),
            "/mnt/c/"
        );

        // assert_eq!(&crate::wsl::wsl_path_or_self("C:", true /*unix*/), "/mnt/c"); wslpath unexpectedly returns C:
    }

    #[test]
    fn is_windows_or_wsl() {
        println!("wsl::tests::is_windows_or_wsl()");
        assert_eq!(
            super::is_windows_or_wsl(),
            true,
            "Run the tests against the Linux binary under WSL."
        );
    }

    #[test]
    fn is_windows() {
        println!("wsl::tests::is_windows()");
        assert_eq!(
            super::is_windows(),
            false,
            "Run the tests against the Linux binary under WSL."
        );
    }

    #[test]
    fn is_wsl() {
        println!("wsl::tests::is_wsl()");
        assert_eq!(
            super::is_wsl(),
            true,
            "Run the tests against the Linux binary under WSL."
        );
    }
}

2 thoughts on “Anatomy of a Rust Program, Part VI: /src/wsl.rs

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: