use big_bytes::BigByte;
use issues::issue_stats;
mod issues;
const GITHUB_API_REPO_URL: &str = "https://api.github.com/repos";
pub type Error = Box<dyn std::error::Error>;
type Response = serde_json::Value;
pub type Result<T> = std::result::Result<T, Error>;
#[derive(Debug)]
pub struct Repo {
name: String,
size: f64,
stars: u64,
forks: u64,
open_issues: u64,
closed_issues: u64,
open_pull_requests: u64,
closed_pull_requests: u64,
}
impl Repo {
pub fn new(user: &str, repo: &str) -> Result<Self> {
let repo_data = repo_stats(user, repo)?;
let name = repo_data["name"]
.as_str()
.ok_or(r#""name" is not a string"#)?
.to_string();
let size = repo_data["size"]
.as_f64()
.ok_or(r#""size" cannot be read as f64"#)?;
let stars = repo_data["stargazers_count"]
.as_u64()
.ok_or(r#""stars" cannot be read as u64"#)?;
let forks = repo_data["forks"]
.as_u64()
.ok_or(r#""forks_count" cannot be read as u64"#)?;
let (open_issues, closed_issues, open_pull_requests, closed_pull_requests) =
issue_stats(user, repo)?;
let repo = Repo {
name,
size,
stars,
forks,
open_issues,
closed_issues,
open_pull_requests,
closed_pull_requests,
};
Ok(repo)
}
pub fn name(&self) -> &str {
&self.name
}
pub fn size(&self) -> f64 {
self.size
}
pub fn human_size(&self, precision: usize) -> String {
(self.size * 1024_f64).big_byte(precision)
}
pub fn stars(&self) -> u64 {
self.stars
}
pub fn forks(&self) -> u64 {
self.forks
}
pub fn open_issues(&self) -> u64 {
self.open_issues
}
pub fn closed_issues(&self) -> u64 {
self.closed_issues
}
pub fn open_pull_requests(&self) -> u64 {
self.open_pull_requests
}
pub fn closed_pull_requests(&self) -> u64 {
self.closed_pull_requests
}
}
fn repo_api_url(user: &str, repo: &str) -> String {
format!("{}/{}/{}", GITHUB_API_REPO_URL, user, repo)
}
fn repo_stats(user: &str, repo: &str) -> Result<Response> {
let response: Response = reqwest::get(&repo_api_url(user, repo))?.json()?;
Ok(response)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn it_works() {
println!("{:#?}", repo_stats("rust-lang", "rust").unwrap());
assert!(true);
}
}