opener-0.4.1/Cargo.toml.orig000064400000000000000000000012341354447630500140740ustar0000000000000000[package] name = "opener" version = "0.4.1" authors = ["Brian Bowman "] edition = "2018" description = "Open a file or link using the system default program." repository = "https://github.com/Seeker14491/opener" readme = "../README.md" keywords = ["open", "default", "launcher", "browser"] license = "MIT OR Apache-2.0" [badges] appveyor = { repository = "Seeker14491/opener", branch = "master", service = "github" } travis-ci = { repository = "Seeker14491/opener", branch = "master" } maintenance = { status = "passively-maintained" } [dependencies] [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["shellapi"] } opener-0.4.1/Cargo.toml0000644000000022370000000000000103670ustar00# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO # # When uploading crates to the registry Cargo will automatically # "normalize" Cargo.toml files for maximal compatibility # with all versions of Cargo and also rewrite `path` dependencies # to registry (e.g., crates.io) dependencies # # If you believe there's an error in this file please file an # issue against the rust-lang/cargo repository. If you're # editing this file be aware that the upstream Cargo.toml # will likely look very different (and much more reasonable) [package] edition = "2018" name = "opener" version = "0.4.1" authors = ["Brian Bowman "] description = "Open a file or link using the system default program." readme = "../README.md" keywords = ["open", "default", "launcher", "browser"] license = "MIT OR Apache-2.0" repository = "https://github.com/Seeker14491/opener" [dependencies] [target."cfg(windows)".dependencies.winapi] version = "0.3" features = ["shellapi"] [badges.appveyor] branch = "master" repository = "Seeker14491/opener" service = "github" [badges.maintenance] status = "passively-maintained" [badges.travis-ci] branch = "master" repository = "Seeker14491/opener" opener-0.4.1/Cargo.toml.orig0000644000000012340000000000000113220ustar00[package] name = "opener" version = "0.4.1" authors = ["Brian Bowman "] edition = "2018" description = "Open a file or link using the system default program." repository = "https://github.com/Seeker14491/opener" readme = "../README.md" keywords = ["open", "default", "launcher", "browser"] license = "MIT OR Apache-2.0" [badges] appveyor = { repository = "Seeker14491/opener", branch = "master", service = "github" } travis-ci = { repository = "Seeker14491/opener", branch = "master" } maintenance = { status = "passively-maintained" } [dependencies] [target.'cfg(windows)'.dependencies] winapi = { version = "0.3", features = ["shellapi"] } opener-0.4.1/LICENSE-APACHE000064400000000000000000000000211346265505700131240ustar0000000000000000../LICENSE-APACHEopener-0.4.1/LICENSE-MIT000064400000000000000000000000161346265505700126400ustar0000000000000000../LICENSE-MITopener-0.4.1/LICENSE-THIRD-PARTY000064400000000000000000000000261346265505700137570ustar0000000000000000../LICENSE-THIRD-PARTYopener-0.4.1/Makefile.toml000064400000000000000000000002301347464047300136130ustar0000000000000000[tasks.clean-docs] command = "cargo" args = ["clean", "--doc"] [tasks.pre-release] dependencies = [ "check-format", "test", "clean-docs" ] opener-0.4.1/release.toml000064400000000000000000000002611354447513000135140ustar0000000000000000pre-release-commit-message = "Release v{{version}}" tag-message = "{{crate_name}} version {{version}}" no-dev-version = true pre-release-hook = ["cargo", "make", "pre-release"] opener-0.4.1/src/lib.rs000064400000000000000000000136741354004470500131120ustar0000000000000000//! This crate provides the [`open`] function, which opens a file or link with the default program //! configured on the system. //! //! ```no_run //! # fn main() -> Result<(), ::opener::OpenError> { //! // open a website //! opener::open("https://www.rust-lang.org")?; //! //! // open a file //! opener::open("../Cargo.toml")?; //! # Ok(()) //! # } //! ``` //! //! ## Platform Implementation Details //! On Windows the `ShellExecuteW` Windows API function is used. On Mac the system `open` command is //! used. On other platforms, the `xdg-open` script is used. The system `xdg-open` is not used; //! instead a version is embedded within this library. #![warn( rust_2018_idioms, deprecated_in_future, macro_use_extern_crate, missing_debug_implementations, unused_labels, unused_qualifications, clippy::cast_possible_truncation )] #[cfg(target_os = "windows")] use crate::windows::open_sys; use std::{ error::Error, ffi::OsStr, fmt::{self, Display, Formatter}, io, process::ExitStatus, }; /// An error type representing the failure to open a path. Possibly returned by the [`open`] /// function. /// /// The `ExitStatus` variant will never be returned on Windows. #[derive(Debug)] pub enum OpenError { /// An IO error occurred. Io(io::Error), /// The command exited with a non-zero exit status. ExitStatus { /// A string that identifies the command. cmd: &'static str, /// The failed process's exit status. status: ExitStatus, /// Anything the process wrote to stderr. stderr: String, }, } impl Display for OpenError { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { match self { OpenError::Io(_) => { write!(f, "IO error")?; } OpenError::ExitStatus { cmd, status, stderr, } => { write!( f, "command '{}' did not execute successfully; {}", cmd, status )?; let stderr = stderr.trim(); if !stderr.is_empty() { write!(f, "\ncommand stderr:\n{}", stderr)?; } } } Ok(()) } } impl Error for OpenError { fn source(&self) -> Option<&(dyn Error + 'static)> { match self { OpenError::Io(inner) => Some(inner), OpenError::ExitStatus { .. } => None, } } } impl From for OpenError { fn from(err: io::Error) -> Self { OpenError::Io(err) } } /// Opens a file or link with the system default program. /// /// Note that a path like "rustup.rs" could potentially refer to either a file or a website. If you /// want to open the website, you should add the "http://" prefix, for example. /// /// Also note that a result of `Ok(())` just means a way of opening the path was found, and no error /// occurred as a direct result of opening the path. Errors beyond that point aren't caught. For /// example, `Ok(())` would be returned even if a file was opened with a program that can't read the /// file, or a dead link was opened in a browser. pub fn open

(path: P) -> Result<(), OpenError> where P: AsRef, { open_sys(path.as_ref()) } #[cfg(target_os = "windows")] mod windows { use super::OpenError; use std::{ffi::OsStr, io, os::windows::ffi::OsStrExt, ptr}; use winapi::{ctypes::c_int, um::shellapi::ShellExecuteW}; pub fn open_sys(path: &OsStr) -> Result<(), OpenError> { const SW_SHOW: c_int = 5; let path = convert_path(path)?; let operation: Vec = OsStr::new("open\0").encode_wide().collect(); let result = unsafe { ShellExecuteW( ptr::null_mut(), operation.as_ptr(), path.as_ptr(), ptr::null(), ptr::null(), SW_SHOW, ) }; if result as c_int > 32 { Ok(()) } else { Err(io::Error::last_os_error().into()) } } fn convert_path(path: &OsStr) -> io::Result> { let mut maybe_result: Vec = path.encode_wide().collect(); if maybe_result.iter().any(|&u| u == 0) { return Err(io::Error::new( io::ErrorKind::InvalidInput, "path contains NUL byte(s)", )); } maybe_result.push(0); Ok(maybe_result) } } #[cfg(target_os = "macos")] fn open_sys(path: &OsStr) -> Result<(), OpenError> { open_not_windows("open", path, &[], None, "open") } #[cfg(not(any(target_os = "windows", target_os = "macos")))] fn open_sys(path: &OsStr) -> Result<(), OpenError> { const XDG_OPEN_SCRIPT: &[u8] = include_bytes!("xdg-open"); open_not_windows( "sh", path, &["-s"], Some(XDG_OPEN_SCRIPT), "xdg-open (internal)", ) } #[cfg(not(target_os = "windows"))] fn open_not_windows( cmd: &str, path: &OsStr, extra_args: &[&str], piped_input: Option<&[u8]>, cmd_friendly_name: &'static str, ) -> Result<(), OpenError> { use std::{ io::{Read, Write}, process::{Command, Stdio}, }; let stdin_type = if piped_input.is_some() { Stdio::piped() } else { Stdio::null() }; let mut cmd = Command::new(cmd) .args(extra_args) .arg(path) .stdin(stdin_type) .stdout(Stdio::null()) .stderr(Stdio::piped()) .spawn()?; if let Some(stdin) = cmd.stdin.as_mut() { stdin.write_all(piped_input.unwrap())?; } let exit_status = cmd.wait()?; if exit_status.success() { Ok(()) } else { let mut stderr = String::new(); cmd.stderr.as_mut().unwrap().read_to_string(&mut stderr)?; Err(OpenError::ExitStatus { cmd: cmd_friendly_name, status: exit_status, stderr, }) } } opener-0.4.1/.cargo_vcs_info.json0000644000000001120000000000000123570ustar00{ "git": { "sha1": "25b295a345f85eff7587cc48416738f03a4a4f36" } }