crate_paths_cli_core/backend/rustup/
mod.rs1pub mod error;
2
3use super::BackendError;
4use crate::error::CoreError;
5use crate::item::ItemEntry;
6use crate::parser;
7use error::RustupBackendError;
8use std::path::PathBuf;
9use std::process::Command;
10
11fn fetch_std_all_items_html(crate_name: &str) -> Result<String, RustupBackendError> {
12 let output = Command::new("rustup")
13 .args(["doc", "--path"])
14 .output()
15 .map_err(RustupBackendError::RustupDocExecution)?;
16
17 if !output.status.success() {
18 return Err(RustupBackendError::RustupDocStatus(
19 output.status.code().unwrap_or(1),
20 ));
21 }
22
23 let doc_path_str = String::from_utf8(output.stdout)?;
24 let trimmed_doc_path_str = doc_path_str.trim();
25
26 let mut doc_root_path = PathBuf::from(trimmed_doc_path_str);
27
28 if doc_root_path.is_file() {
29 if let Some(parent_dir) = doc_root_path.parent() {
30 doc_root_path = parent_dir.to_path_buf();
31 } else {
32 return Err(RustupBackendError::DocPathInvalid(PathBuf::from(
33 trimmed_doc_path_str,
34 )));
35 }
36 }
37
38 if !doc_root_path.is_dir() {
39 return Err(RustupBackendError::DocPathNotFound(doc_root_path));
40 }
41
42 let all_html_path = doc_root_path.join(crate_name).join("all.html");
43
44 if !all_html_path.is_file() {
45 return Err(RustupBackendError::DocFileNotFound(all_html_path));
46 }
47
48 std::fs::read_to_string(&all_html_path)
49 .map_err(|e| RustupBackendError::FileRead(all_html_path, e))
50}
51
52pub fn process(crate_name: &str) -> Result<Vec<ItemEntry>, CoreError> {
53 let html_content = fetch_std_all_items_html(crate_name)
54 .map_err(BackendError::from)
55 .map_err(CoreError::from)?;
56
57 parser::parse_html_to_items(crate_name, &html_content).map_err(CoreError::from)
58}