use std::io;
#[cfg(not(target_os = "windows"))]
use std::process::Command;
pub fn open_url(url: &str) -> io::Result<()> {
#[cfg(target_os = "windows")]
{
open_url_windows(url)
}
#[cfg(target_os = "macos")]
{
Command::new("open").arg(url).spawn()?;
Ok(())
}
#[cfg(all(unix, not(target_os = "macos")))]
{
Command::new("xdg-open").arg(url).spawn()?;
Ok(())
}
}
#[cfg(target_os = "windows")]
fn open_url_windows(url: &str) -> io::Result<()> {
use std::ptr;
use windows_sys::Win32::UI::{Shell::ShellExecuteW, WindowsAndMessaging::SW_SHOWNORMAL};
let operation = wide_null("open");
let target = wide_null(url);
let result = unsafe {
ShellExecuteW(
ptr::null_mut(),
operation.as_ptr(),
target.as_ptr(),
ptr::null(),
ptr::null(),
SW_SHOWNORMAL,
)
} as isize;
if result <= 32 {
let os_error = i32::try_from(result).unwrap_or(i32::MIN);
Err(io::Error::from_raw_os_error(os_error))
} else {
Ok(())
}
}
#[cfg(target_os = "windows")]
fn wide_null(value: &str) -> Vec<u16> {
use std::{ffi::OsStr, os::windows::ffi::OsStrExt};
OsStr::new(value).encode_wide().chain(Some(0)).collect()
}