Skip to content

Commit

Permalink
apply suggestions
Browse files Browse the repository at this point in the history
  • Loading branch information
matoous committed Feb 12, 2023
1 parent 8aa9bce commit 02fce60
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 63 deletions.
21 changes: 13 additions & 8 deletions src/haiku.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,24 @@ 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(path).status_without_output().into_result()
Command::new("/bin/open")
.arg(path.as_ref())
.without_io()
.status()
.into_result()
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Command::new(app.into())
.arg(path.as_ref())
.status_without_output()
.without_io()
.status()
.into_result()
}

pub fn commands<T: AsRef<OsStr>>(path: T) -> impl Iterator<Item = Command> {
let mut cmd = Command::new("/bin/open");
cmd.arg(path.as_ref());
Some(cmd).into_iter()
}
22 changes: 14 additions & 8 deletions src/ios.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,13 @@ 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(path).status_without_output().into_result()
Command::new("uiopen")
.arg("--url")
.arg(path.as_ref())
.without_io()
.status()
.into_result()
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Expand All @@ -18,6 +17,13 @@ pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()>
.arg(path.as_ref())
.arg("--bundleid")
.arg(app.into())
.status_without_output()
.without_io()
.status()
.into_result()
}

pub fn commands<T: AsRef<OsStr>>(path: T) -> impl Iterator<Item = Command> {
let mut cmd = Command::new("uiopen");
cmd.arg("--url").arg(path.as_ref());
Some(cmd).into_iter()
}
27 changes: 16 additions & 11 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@
//! open::with("http://rust-lang.org", "firefox").unwrap();
//! ```
//!
//! Or obtain the command without running it.
//! Or obtain commands for opening the URL without running them.
//!
//! ```no_run
//! let cmd = open::command("http://rust-lang.org");
//! let cmds = open::commands("http://rust-lang.org");
//! ```
//!
//! # Notes
Expand Down Expand Up @@ -137,16 +137,19 @@ 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.
/// Get iterator over commands that open path with the default application.
/// Iterator over Commands is returned as for certain platforms there are
/// multiple command options.
/// It is the responsibility of the callee to try all commands.
///
/// # Examples
///
/// ```no_run
/// let path = "http://rust-lang.org";
/// let cmd = open::command(path);
/// let cmds = open::commands(path);
/// ```
pub fn command<'a, T: AsRef<OsStr>>(path: T) -> Command {
os::command(path)
pub fn commands<T: AsRef<OsStr>>(path: T) -> impl Iterator<Item = Command> {
os::commands(path)
}

/// Open path with the default application in a new thread.
Expand Down Expand Up @@ -200,17 +203,19 @@ impl IntoResult<io::Result<()>> for std::os::raw::c_int {
}

trait CommandExt {
fn status_without_output(&mut self) -> io::Result<std::process::ExitStatus>;
fn without_io(&mut self) -> &mut Self;
fn status(&mut self) -> io::Result<std::process::ExitStatus>;
}

impl CommandExt for Command {
fn status_without_output(&mut self) -> io::Result<std::process::ExitStatus> {
let mut process = self
.stdin(Stdio::null())
fn without_io(&mut self) -> &mut Self {
self.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.spawn()?;
}

fn status(&mut self) -> io::Result<std::process::ExitStatus> {
let mut process = self.spawn()?;
process.wait()
}
}
Expand Down
21 changes: 13 additions & 8 deletions src/macos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,26 @@ 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(path).status_without_output().into_result()
Command::new("/usr/bin/open")
.arg(path.as_ref())
.without_io()
.status()
.into_result()
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Command::new("/usr/bin/open")
.arg(path.as_ref())
.arg("-a")
.arg(app.into())
.status_without_output()
.without_io()
.status()
.into_result()
}

pub fn commands<T: AsRef<OsStr>>(path: T) -> impl Iterator<Item = Command> {
let mut cmd = Command::new("/usr/bin/open");
cmd.arg(path.as_ref());
Some(cmd).into_iter()
}
50 changes: 30 additions & 20 deletions src/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{

use crate::{CommandExt, IntoResult};

pub fn command<T: AsRef<OsStr>>(path: T) -> Command {
pub fn commands<T: AsRef<OsStr>>(path: T) -> impl Iterator<Item = Command> {
let path = path.as_ref();
let open_handlers = [
("xdg-open", &[path] as &[_]),
Expand All @@ -18,33 +18,43 @@ pub fn command<T: AsRef<OsStr>>(path: T) -> Command {
("wslview", &[&wsl_path(path)]),
];

for (command, args) in &open_handlers {
let result = Command::new(command).status_without_output();

if let Ok(status) = result {
if status.success() {
let mut cmd = Command::new(command);
cmd.args(*args);
return cmd;
};
};
}

// fallback to xdg-open
let (command, args) = &open_handlers[0];
let mut cmd = Command::new(command);
cmd.args(*args);
cmd
open_handlers.into_iter().map(|(cmd, args)| {
let mut cmd = Command::new("/usr/bin/open");
cmd.args(args);
cmd
})
}

pub fn that<T: AsRef<OsStr>>(path: T) -> io::Result<()> {
command(path).status_without_output().into_result()
let mut unsuccessful = None;
let mut io_error = None;

for cmd in commands(path) {
let result = cmd.without_io().status().into_result();
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)),
}
}

Err(unsuccessful
.or(io_error)
.expect("successful cases don't get here"))
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Command::new(app.into())
.arg(path.as_ref())
.status_without_output()
.without_io()
.status()
.into_result()
}

Expand Down
22 changes: 14 additions & 8 deletions src/windows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,27 @@ 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("cmd");
cmd.arg("/c").arg("start").arg(path.as_ref());
cmd
}

pub fn that<T: AsRef<OsStr>>(path: T) -> io::Result<()> {
command(path).status_without_output().into_result()
Command::new("cmd")
.arg("/c")
.arg("start")
.arg(path.as_ref())
.without_io()
.status()
}

pub fn with<T: AsRef<OsStr>>(path: T, app: impl Into<String>) -> io::Result<()> {
Command::new("cmd")
.arg("/c")
.arg(app.into())
.arg(path.as_ref())
.status_without_output()
.without_io()
.status()
.into_result()
}

pub fn commands<T: AsRef<OsStr>>(path: T) -> impl Iterator<Item = Command> {
let mut cmd = Command::new("cmd");
cmd.arg("/c").arg("start").arg(path.as_ref());
Some(cmd).into_iter()
}

0 comments on commit 02fce60

Please sign in to comment.