moire_web/util/
source_path.rs1static SYSROOT_BY_HASH: std::sync::OnceLock<std::collections::HashMap<String, String>> =
2 std::sync::OnceLock::new();
3
4fn sysroot_by_commit_hash() -> &'static std::collections::HashMap<String, String> {
5 SYSROOT_BY_HASH.get_or_init(|| {
6 let mut map = std::collections::HashMap::new();
7 let home = match std::env::var("RUSTUP_HOME")
8 .ok()
9 .or_else(|| std::env::var("HOME").ok().map(|h| format!("{h}/.rustup")))
10 {
11 Some(h) => h,
12 None => return map,
13 };
14 let toolchains_dir = format!("{home}/toolchains");
15 let entries = match std::fs::read_dir(&toolchains_dir) {
16 Ok(e) => e,
17 Err(_) => return map,
18 };
19 for entry in entries.flatten() {
20 let intro = entry.path().join("share/doc/rust/html/intro.html");
21 let html = match std::fs::read_to_string(&intro) {
22 Ok(s) => s,
23 Err(_) => continue,
24 };
25 let needle = "/rust-lang/rust/commit/";
26 let commit_hash = html.find(needle).and_then(|pos| {
27 let after = &html[pos + needle.len()..];
28 let end = after
29 .find(|c: char| !c.is_ascii_hexdigit())
30 .unwrap_or(after.len());
31 let hash = &after[..end];
32 if hash.len() == 40 {
33 Some(hash.to_owned())
34 } else {
35 None
36 }
37 });
38 if let Some(hash) = commit_hash {
39 let sysroot = entry.path().to_string_lossy().into_owned();
40 map.insert(hash, sysroot);
41 }
42 }
43 map
44 })
45}
46
47pub fn resolve_source_path(path: &str) -> std::borrow::Cow<'_, str> {
49 if let Some(after_rustc) = path.strip_prefix("/rustc/")
50 && let Some(slash) = after_rustc.find('/')
51 {
52 let hash = &after_rustc[..slash];
53 if hash.len() == 40 && hash.chars().all(|c| c.is_ascii_hexdigit()) {
54 let rest = &after_rustc[slash + 1..];
55 if let Some(sysroot) = sysroot_by_commit_hash().get(hash) {
56 let remapped = format!("{sysroot}/lib/rustlib/src/rust/{rest}");
57 return std::borrow::Cow::Owned(remapped);
58 }
59 }
60 }
61 std::borrow::Cow::Borrowed(path)
62}