memtrace_utils/
common.rs

1use std::{fs, io};
2use std::fs::File;
3use std::io::BufWriter;
4use std::path::Path;
5use anyhow::Context;
6
7pub fn download_lib_if_needed(lib_dir: impl AsRef<Path>, lib_version: &str) -> anyhow::Result<String> {
8    if lib_dir.as_ref().is_file() {
9        anyhow::bail!("lib_dir is not a directory");
10    }
11
12    let lib_file = lib_dir
13        .as_ref()
14        .join(format!("libmemtrace_{}.dylib", lib_version));
15
16    if lib_file.exists() {
17        return Ok(lib_file.to_str().unwrap().to_string());
18    }
19
20    println!("Loading libmemtrace version {}", lib_version);
21
22    fs::create_dir_all(lib_dir).context("failed to create dirs")?;
23
24    let mut response = reqwest::blocking::get(format!(
25        "https://github.com/blkmlk/memtrace-lib/releases/download/{}/libmemtrace_lib.dylib",
26        lib_version
27    ))
28        .context("failed to download libmemtrace.dylib")?;
29
30    if !response.status().is_success() {
31        anyhow::bail!(
32            "failed to download libmemtrace.dylib. status: {}",
33            response.status()
34        );
35    }
36
37    let mut out_file =
38        BufWriter::new(File::create(&lib_file).context("failed to create output file")?);
39
40    io::copy(&mut response, &mut out_file).context("failed to write output file")?;
41
42    println!(
43        "Successfully loaded libmemtrace.dylib version {}",
44        lib_version
45    );
46
47    Ok(lib_file.to_str().unwrap().to_string())
48}