1use std::path::Path;
4use std::path::PathBuf;
5use std::process::Command;
6
7use crate::CargoResult;
8use crate::GlobalContext;
9use crate::util::context::PathAndArgs;
10
11pub fn open(path: &Path, gctx: &GlobalContext) -> CargoResult<()> {
17 let config_browser = {
18 let cfg: Option<PathAndArgs> = gctx.get("doc.browser")?;
19 cfg.map(|path_args| (path_args.path.resolve_program(gctx), path_args.args))
20 };
21
22 let mut shell = gctx.shell();
23 let link = shell.err_file_hyperlink(&path);
24 shell.status("Opening", format!("{link}{}{link:#}", path.display()))?;
25
26 let browser =
27 config_browser.or_else(|| Some((PathBuf::from(gctx.get_env_os("BROWSER")?), Vec::new())));
28
29 match browser {
30 Some((browser, initial_args)) => {
31 if let Err(e) = Command::new(&browser).args(initial_args).arg(path).status() {
32 shell.warn(format!(
33 "Couldn't open docs with {}: {}",
34 browser.to_string_lossy(),
35 e
36 ))?;
37 }
38 }
39 None => {
40 if let Err(e) = opener::open(&path) {
41 let e = e.into();
42 crate::display_warning_with_error("couldn't open docs", &e, &mut shell);
43 }
44 }
45 };
46
47 Ok(())
48}