1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#![warn(clippy::all, clippy::pedantic, clippy::nursery)]

use std::{path::PathBuf, str::FromStr};

fn err_to_string<E: std::fmt::Debug>(e: E) -> String {
    format!("{:?}", e)
}

/// # Errors
pub fn get_code(lib: &str) -> Result<(String, String), String> {
    let url = url::Url::from_str(lib).map_err(err_to_string)?;

    let segments = url
        .path_segments()
        .ok_or_else(|| "lib url has no segments".to_string())?;

    let filename = segments
        .last()
        .ok_or_else(|| "lib url has no segments".to_string())?;

    let mut file = PathBuf::from_str("target").map_err(err_to_string)?;
    file.push(filename);

    if let Ok(code) = std::fs::read_to_string(&file) {
        println!("[{}] - using [{}]", filename, file.display());
        Ok((filename.to_string(), code))
    } else {
        println!(
            "[{}] - Downloading [{}] to [{}]",
            filename,
            lib,
            file.display()
        );
        match ureq::get(lib).call() {
            Ok(response) => {
                let mut reader = response.into_reader();

                #[allow(clippy::let_underscore_drop)]
                let _ = std::fs::remove_file(&file);
                let mut writer = std::fs::File::create(&file).map_err(err_to_string)?;
                #[allow(clippy::let_underscore_drop)]
                let _ = std::io::copy(&mut reader, &mut writer);

                std::fs::read_to_string(&file)
                    .map_err(err_to_string)
                    .map(|code| (filename.to_string(), code))
            }
            Err(e) => Err(format!("{:?}", e)),
        }
    }
}