From fdd2ef013fe7dee1767694e229f4653f16d4ab8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Matou=C5=A1=20Dzivjak?= Date: Sun, 5 Feb 2023 18:15:38 +0000 Subject: [PATCH] feat: add command function to return std::Command Adds new `command` function that returns the underlying `std::Command` that would be called to open given path. Related: https://github.com/Byron/open-rs/pull/63 Related: https://github.com/helix-editor/helix/pull/5820 --- src/haiku.rs | 11 +++++++---- src/ios.rs | 12 +++++++----- src/lib.rs | 18 +++++++++++++++++ src/macos.rs | 11 +++++++---- src/unix.rs | 52 +++++++++++++++++++++++++------------------------- src/windows.rs | 17 ++++++++--------- 6 files changed, 73 insertions(+), 48 deletions(-) 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..1d9c102 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,18 @@ 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); +/// ``` +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..14bbca7 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -8,39 +8,39 @@ 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] as &[_]), + ("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() { + let mut cmd = Command::new(command); + cmd.args(*args); + return cmd; + }; + }; } - 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<()> { diff --git a/src/windows.rs b/src/windows.rs index b2b8658..404c803 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -1,18 +1,17 @@ -use std::{ffi::OsStr, io}; +use std::{ffi::OsStr, io, process::Command}; -use crate::{CommandExt, IntoResult}; +pub fn command>(path: T) -> Command { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg("start").arg(path.as_ref()); + cmd +} pub fn that>(path: T) -> io::Result<()> { - std::process::Command::new("cmd") - .arg("/c") - .arg("start") - .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<()> { - std::process::Command::new("cmd") + Command::new("cmd") .arg("/c") .arg(app.into()) .arg(path.as_ref())