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}