use regex::bytes::Regex;
use std::{
io::{Cursor, Write},
path::Path,
};
#[derive(Clone)]
pub struct CommitHash {
hash: String,
tag: Option<String>,
}
impl CommitHash {
pub fn commit_hash_to_string(&self) -> &String {
&self.hash
}
pub fn search_rustc_version(&self) -> Option<String> {
match search_rustc_version_from_commit(&self.hash) {
Some(version) => Some(version),
None => get_latest_rustc_version(),
}
}
}
#[derive(Clone)]
pub struct RustcInformation {
hash: CommitHash,
}
impl RustcInformation {
pub fn get_commit_hash(&self) -> &CommitHash {
&self.hash
}
pub fn from_file(filepath: &Path) -> Result<Option<RustcInformation>, std::io::Error> {
let content = std::fs::read(&filepath)?;
Ok(RustcInformation::from_buffer(&content))
}
pub fn from_buffer(buffer: &Vec<u8>) -> Option<RustcInformation> {
let version_regex = Regex::new(r"rustc/(?<hash>[a-z0-9]+)").unwrap();
for c in version_regex.captures_iter(buffer.as_ref()) {
let v = String::from_utf8(c.name("hash").unwrap().as_bytes().to_vec()).unwrap();
return Some(RustcInformation {
hash: CommitHash { hash: v, tag: None },
});
}
None
}
}
fn search_rustc_version_from_commit(hash: &str) -> Option<String> {
let tag_regex = Regex::new(r##"href="/rust-lang/rust/releases/tag/(?<tag>[0-9\.]+)"##).unwrap();
let url = format!(
"https://github.com/rust-lang/rust/branch_commits/{:#}",
hash
);
let mut result = None;
let client = reqwest::blocking::Client::new();
let response = client.get(&url).send().unwrap();
let content = Cursor::new(response.bytes().unwrap());
let ca = tag_regex.captures_iter(content.get_ref());
for c in ca {
let v = String::from_utf8(c.name("tag").unwrap().as_bytes().to_vec()).unwrap();
result = Some(v);
}
result
}
fn get_latest_rustc_version() -> Option<String> {
let tag_regex = Regex::new(r##"/rust-lang/rust/releases/tag/(?<tag>[0-9\.]+)"##).unwrap();
let url = String::from("https://github.com/rust-lang/rust/tags");
let mut result = None;
let client = reqwest::blocking::Client::new();
let response = client.get(&url).send().unwrap();
let content = Cursor::new(response.bytes().unwrap());
let ca = tag_regex.captures_iter(content.get_ref());
for c in ca {
let v = String::from_utf8(c.name("tag").unwrap().as_bytes().to_vec()).unwrap();
result = Some(v);
break;
}
result
}