#![allow(dead_code)]
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Repository {
pub id: i64,
pub name: String,
pub full_name: String,
pub owner: String,
pub description: Option<String>,
pub url: String,
pub clone_url: String,
pub default_branch: String,
pub is_private: bool,
pub is_fork: bool,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub pushed_at: Option<DateTime<Utc>>,
pub stargazers_count: i64,
pub language: Option<String>,
pub languages: HashMap<String, i64>,
pub topics: Vec<String>,
pub size: i64,
pub open_issues_count: i64,
pub forks_count: i64,
}
impl Repository {
pub fn from_octocrab(repo: &octocrab::models::Repository) -> Self {
Self {
id: repo.id.0 as i64,
name: repo.name.clone(),
full_name: repo.full_name.clone().unwrap_or_default(),
owner: repo.owner.as_ref().map(|o| o.login.clone()).unwrap_or_default(),
description: repo.description.clone(),
url: repo.html_url.as_ref().map(|u| u.to_string()).unwrap_or_default(),
clone_url: repo.clone_url.as_ref().map(|u| u.to_string()).unwrap_or_default(),
default_branch: repo.default_branch.clone().unwrap_or_else(|| "main".to_string()),
is_private: repo.private.unwrap_or(false),
is_fork: repo.fork.unwrap_or(false),
created_at: repo.created_at.unwrap_or_else(Utc::now),
updated_at: repo.updated_at.unwrap_or_else(Utc::now),
pushed_at: repo.pushed_at,
stargazers_count: repo.stargazers_count.unwrap_or(0) as i64,
language: repo.language.as_ref().and_then(|v| v.as_str()).map(|s| s.to_string()),
languages: HashMap::new(),
topics: repo.topics.clone().unwrap_or_default(),
size: repo.size.unwrap_or(0) as i64,
open_issues_count: repo.open_issues_count.unwrap_or(0) as i64,
forks_count: repo.forks_count.unwrap_or(0) as i64,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Branch {
pub name: String,
pub commit_sha: String,
pub commit_url: String,
pub protected: bool,
pub last_commit_date: Option<DateTime<Utc>>,
pub last_commit_message: Option<String>,
pub last_commit_author: Option<String>,
}
impl Branch {
pub fn from_octocrab(branch: &octocrab::models::repos::Branch) -> Self {
Self {
name: branch.name.clone(),
commit_sha: branch.commit.sha.clone(),
commit_url: branch.commit.url.to_string(),
protected: branch.protected,
last_commit_date: None,
last_commit_message: None,
last_commit_author: None,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Commit {
pub sha: String,
pub message: String,
pub author_name: Option<String>,
pub author_email: Option<String>,
pub author_date: Option<DateTime<Utc>>,
pub committer_name: Option<String>,
pub committer_email: Option<String>,
pub committer_date: Option<DateTime<Utc>>,
pub url: String,
}
impl Commit {
pub fn from_octocrab(commit: &octocrab::models::repos::RepoCommit) -> Self {
let author_name = commit.commit.author.as_ref()
.map(|a| a.user.name.clone());
let author_email = commit.commit.author.as_ref()
.map(|a| a.user.email.clone());
let author_date = commit.commit.author.as_ref()
.and_then(|a| a.date);
let committer_name = commit.commit.committer.as_ref()
.map(|c| c.user.name.clone());
let committer_email = commit.commit.committer.as_ref()
.map(|c| c.user.email.clone());
let committer_date = commit.commit.committer.as_ref()
.and_then(|c| c.date);
Self {
sha: commit.sha.clone(),
message: commit.commit.message.clone(),
author_name,
author_email,
author_date,
committer_name,
committer_email,
committer_date,
url: commit.html_url.to_string(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct PullRequest {
pub id: i64,
pub number: i64,
pub title: String,
pub body: Option<String>,
pub state: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub closed_at: Option<DateTime<Utc>>,
pub merged_at: Option<DateTime<Utc>>,
pub author: String,
pub head_branch: String,
pub base_branch: String,
pub url: String,
pub additions: i64,
pub deletions: i64,
pub changed_files: i64,
pub labels: Vec<String>,
}
impl PullRequest {
pub fn from_octocrab(pr: &octocrab::models::pulls::PullRequest) -> Self {
Self {
id: pr.id.0 as i64,
number: pr.number as i64,
title: pr.title.clone().unwrap_or_default(),
body: pr.body.clone(),
state: format!("{:?}", pr.state),
created_at: pr.created_at.unwrap_or_else(Utc::now),
updated_at: pr.updated_at.unwrap_or_else(Utc::now),
closed_at: pr.closed_at,
merged_at: pr.merged_at,
author: pr.user.as_ref().map(|u| u.login.clone()).unwrap_or_default(),
head_branch: pr.head.ref_field.clone(),
base_branch: pr.base.ref_field.clone(),
url: pr.html_url.as_ref().map(|u| u.to_string()).unwrap_or_default(),
additions: pr.additions.map(|a| a as i64).unwrap_or(0),
deletions: pr.deletions.map(|d| d as i64).unwrap_or(0),
changed_files: pr.changed_files.map(|c| c as i64).unwrap_or(0),
labels: Vec::new(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Issue {
pub id: i64,
pub number: i64,
pub title: String,
pub body: Option<String>,
pub state: String,
pub created_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub closed_at: Option<DateTime<Utc>>,
pub author: String,
pub url: String,
pub labels: Vec<String>,
pub comments_count: i64,
}
impl Issue {
pub fn from_octocrab(issue: &octocrab::models::issues::Issue) -> Self {
Self {
id: issue.id.0 as i64,
number: issue.number as i64,
title: issue.title.clone(),
body: issue.body.clone(),
state: format!("{:?}", issue.state),
created_at: issue.created_at,
updated_at: issue.updated_at,
closed_at: issue.closed_at,
author: issue.user.login.clone(),
url: issue.html_url.to_string(),
labels: Vec::new(),
comments_count: issue.comments as i64,
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct LanguageStats {
pub languages: HashMap<String, (i64, f64)>, pub total_bytes: i64,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct RepositoryScan {
pub repository: Repository,
pub branches: Vec<Branch>,
pub recent_commits: Vec<Commit>,
pub language_stats: LanguageStats,
pub pull_requests: Vec<PullRequest>,
pub scan_timestamp: DateTime<Utc>,
}
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
pub struct GitHubSummary {
pub total_repos: usize,
pub total_branches: usize,
pub total_commits_30d: usize,
pub total_prs_open: usize,
pub total_prs_merged_30d: usize,
pub total_issues_open: usize,
pub top_languages: Vec<(String, i64)>,
pub most_active_repos: Vec<String>,
pub recent_activity: Vec<ActivityEvent>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ActivityEvent {
pub event_type: String,
pub repo: String,
pub description: String,
pub timestamp: DateTime<Utc>,
pub url: Option<String>,
}