1#![warn(missing_docs)]
14
15use std::process::Command;
16
17#[cfg(windows)]
18use std::os::windows::process::CommandExt;
19
20#[derive(Debug)]
22pub enum Conversion {
23 WindowsToWsl,
25 WslToWindows,
27 WslToWindowsLinuxStyle,
29}
30
31pub fn convert(
50 path: &str,
51 distro: Option<&str>,
52 options: Conversion,
53 force_absolute_path: bool,
54) -> Result<String, Box<dyn std::error::Error>> {
55 let mut args = Vec::new();
56
57 if let Some(distro) = distro {
58 args.push("-d");
59 args.push(distro);
60 }
61 args.push("-e");
62 args.push("wslpath");
63
64 args.push(match options {
67 Conversion::WindowsToWsl => "-u",
68 Conversion::WslToWindows => "-w",
69 Conversion::WslToWindowsLinuxStyle => "-m",
70 });
71
72 if force_absolute_path {
74 args.push("-a");
75 }
76
77 let mut cmd = Command::new("wsl.exe");
78 cmd.args(args);
79 cmd.arg(path.replace('\\', "\\\\"));
80
81 #[cfg(windows)]
89 cmd.creation_flags(0x08000000); let output = cmd
92 .output()
93 .map_err(|e| format!("Error executing wsl.exe: {}", e))?;
94
95 let code = output.status.code().unwrap_or(-1);
96 if code != 0 {
97 return Err(format!("Error getting wslpath: {}", code).into());
98 }
99
100 Ok(std::str::from_utf8(&output.stdout)
101 .map_err(|e| format!("Error converting output to string: {}", e))?
102 .trim()
103 .to_string())
104}
105
106#[cfg(test)]
107mod tests {
108 use crate::{convert, Conversion};
109
110 #[test]
113 fn test_wsl_to_windows() {
114 assert_eq!(
115 convert("/mnt/c", None, Conversion::WslToWindows, false).unwrap_or_default(),
116 "C:\\"
117 );
118 }
119
120 #[test]
121 fn test_wsl_to_windows_absolute() {
122 assert_eq!(
123 convert("/mnt/c", None, Conversion::WslToWindows, true).unwrap_or_default(),
124 "C:\\"
125 );
126 }
127
128 #[test]
129 fn test_wsl_to_windows_linux_style() {
130 assert_eq!(
131 convert("/mnt/c", None, Conversion::WslToWindowsLinuxStyle, false).unwrap_or_default(),
132 "C:/"
133 );
134 }
135
136 #[test]
137 fn test_wsl_to_windows_linux_style_absolute() {
138 assert_eq!(
139 convert("/mnt/c", None, Conversion::WslToWindowsLinuxStyle, true).unwrap_or_default(),
140 "C:/"
141 );
142 }
143
144 #[test]
145 fn test_windows_to_wsl() {
146 assert_eq!(
147 convert("C:/", None, Conversion::WindowsToWsl, false).unwrap_or_default(),
148 "/mnt/c/"
149 );
150 }
151
152 #[test]
153 fn test_windows_to_wsl_absolute() {
154 assert_eq!(
155 convert("C:/", None, Conversion::WindowsToWsl, true).unwrap_or_default(),
156 "/mnt/c/"
157 );
158 }
159}