diff --git a/src/haiku.rs b/src/haiku.rs index 38bbf33..1639c36 100644 --- a/src/haiku.rs +++ b/src/haiku.rs @@ -2,11 +2,14 @@ use std::{ffi::OsStr, io, process::Command}; use crate::{CommandExt, IntoResult}; +pub fn command>(path: T) -> Command { + let mut cmd = Command::new("/bin/open"); + cmd.arg(path.as_ref()); + cmd +} + pub fn that>(path: T) -> io::Result<()> { - Command::new("/bin/open") - .arg(path.as_ref()) - .status_without_output() - .into_result() + command(path).status_without_output().into_result() } pub fn with>(path: T, app: impl Into) -> io::Result<()> { diff --git a/src/ios.rs b/src/ios.rs index 179bf70..a3a71d7 100644 --- a/src/ios.rs +++ b/src/ios.rs @@ -2,12 +2,14 @@ use std::{ffi::OsStr, io, process::Command}; use crate::{CommandExt, IntoResult}; +pub fn command>(path: T) -> Command { + let mut cmd = Command::new("uiopen"); + cmd.arg("--url").arg(path.as_ref()); + cmd +} + pub fn that>(path: T) -> io::Result<()> { - Command::new("uiopen") - .arg("--url") - .arg(path.as_ref()) - .status_without_output() - .into_result() + command(path).status_without_output().into_result() } pub fn with>(path: T, app: impl Into) -> io::Result<()> { diff --git a/src/lib.rs b/src/lib.rs index 256ea15..d6f7eed 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -14,6 +14,12 @@ //! open::with("http://rust-lang.org", "firefox").unwrap(); //! ``` //! +//! Or obtain the command without running it. +//! +//! ```no_run +//! let cmd = open::command("http://rust-lang.org"); +//! ``` +//! //! # Notes //! //! ## Nonblocking operation @@ -131,6 +137,23 @@ pub fn with>(path: T, app: impl Into) -> io::Result<()> os::with(path, app) } +/// Get command that opens path with the default application. +/// +/// # Examples +/// +/// ```no_run +/// let path = "http://rust-lang.org"; +/// let cmd = open::command(path); +/// +/// match cmd.status_without_output().into_result() { +/// Ok(()) => println!("Opened '{}' successfully.", path), +/// Err(err) => panic!("An error occurred when opening '{}': {}", path, err), +/// } +/// ``` +pub fn command<'a, T: AsRef>(path: T) -> Command { + os::command(path) +} + /// Open path with the default application in a new thread. /// /// See documentation of [`that()`] for more details. diff --git a/src/macos.rs b/src/macos.rs index 2575d58..8b99ceb 100644 --- a/src/macos.rs +++ b/src/macos.rs @@ -2,11 +2,14 @@ use std::{ffi::OsStr, io, process::Command}; use crate::{CommandExt, IntoResult}; +pub fn command>(path: T) -> Command { + let mut cmd = Command::new("/usr/bin/open"); + cmd.arg(path.as_ref()); + cmd +} + pub fn that>(path: T) -> io::Result<()> { - Command::new("/usr/bin/open") - .arg(path.as_ref()) - .status_without_output() - .into_result() + command(path).status_without_output().into_result() } pub fn with>(path: T, app: impl Into) -> io::Result<()> { diff --git a/src/unix.rs b/src/unix.rs index 1c807ef..4f22389 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -8,39 +8,37 @@ use std::{ use crate::{CommandExt, IntoResult}; -pub fn that>(path: T) -> io::Result<()> { +pub fn command>(path: T) -> Command { let path = path.as_ref(); let open_handlers = [ - ("xdg-open", &[path] as &[_]), - ("gio", &[OsStr::new("open"), path]), - ("gnome-open", &[path]), - ("kde-open", &[path]), - ("wslview", &[&wsl_path(path)]), + ("xdg-open", &["--version"], &[path]), + ("gio", &["version"], &[OsStr::new("open"), path]), + ("gnome-open", &["--version"], &[path]), + ("kde-open", &["--version"], &[path]), + ("wslview", &["--version"], &[&wsl_path(path)]), ]; - let mut unsuccessful = None; - let mut io_error = None; - - for (command, args) in &open_handlers { - let result = Command::new(command).args(*args).status_without_output(); + for (command, check_args, args) in &open_handlers { + let result = Command::new(command) + .args(*check_args) + .status_without_output(); - match result { - Ok(status) if status.success() => return Ok(()), - Ok(status) => { - unsuccessful = unsuccessful.or_else(|| { - Some(std::io::Error::new( - std::io::ErrorKind::Other, - status.to_string(), - )) - }) - } - Err(err) => io_error = io_error.or(Some(err)), - } + if let Ok(status) = result { + if status.success() { + return Command::new(command).args(*args); + }; + }; } - Err(unsuccessful - .or(io_error) - .expect("successful cases don't get here")) + // fallback to xdg-open + let (command, _, args) = &open_handlers[0]; + let mut cmd = Command::new(command); + cmd.args(*args); + cmd +} + +pub fn that>(path: T) -> io::Result<()> { + command(path).status_without_output().into_result() } pub fn with>(path: T, app: impl Into) -> io::Result<()> {