Skip to content

Commit

Permalink
feat: add command function to return std::Command
Browse files Browse the repository at this point in the history
Adds new `command` function that returns the underlying `std::Command`
that would be called to open given path.

Related: Byron#63
Related: helix-editor/helix#5820
  • Loading branch information
matoous committed Feb 5, 2023
1 parent 0d09f28 commit b20eff3
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 39 deletions.
11 changes: 7 additions & 4 deletions src/haiku.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ use std::{ffi::OsStr, io, process::Command};

use crate::{CommandExt, IntoResult};

pub fn command<T: AsRef<OsStr>>(path: T) -> Command {
let mut cmd = Command::new("/bin/open");
cmd.arg(path.as_ref());
cmd
}

pub fn that<T: AsRef<OsStr>>(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<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Expand Down
12 changes: 7 additions & 5 deletions src/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ use std::{ffi::OsStr, io, process::Command};

use crate::{CommandExt, IntoResult};

pub fn command<T: AsRef<OsStr>>(path: T) -> Command {
let mut cmd = Command::new("uiopen");
cmd.arg("--url").arg(path.as_ref());
cmd
}

pub fn that<T: AsRef<OsStr>>(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<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Expand Down
23 changes: 23 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -131,6 +137,23 @@ pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> 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<OsStr>>(path: T) -> Command {
os::command(path)
}

/// Open path with the default application in a new thread.
///
/// See documentation of [`that()`] for more details.
Expand Down
11 changes: 7 additions & 4 deletions src/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ use std::{ffi::OsStr, io, process::Command};

use crate::{CommandExt, IntoResult};

pub fn command<T: AsRef<OsStr>>(path: T) -> Command {
let mut cmd = Command::new("/usr/bin/open");
cmd.arg(path.as_ref());
cmd
}

pub fn that<T: AsRef<OsStr>>(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<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Expand Down
52 changes: 26 additions & 26 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,39 +8,39 @@ use std::{

use crate::{CommandExt, IntoResult};

pub fn that<T: AsRef<OsStr>>(path: T) -> io::Result<()> {
pub fn command<T: AsRef<OsStr>>(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<T: AsRef<OsStr>>(path: T) -> io::Result<()> {
command(path).status_without_output().into_result()
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Expand Down

0 comments on commit b20eff3

Please sign in to comment.