use crate::doctor::{CheckStatus, DoctorReport};
use crate::error::Result;
use crate::worktree::{self, BranchStatus, WorktreeInfo};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct JsonStatus {
pub is_dirty: bool,
pub has_upstream: bool,
pub ahead: usize,
pub behind: usize,
pub unknown: bool,
}
impl From<&BranchStatus> for JsonStatus {
fn from(s: &BranchStatus) -> Self {
Self {
is_dirty: s.is_dirty,
has_upstream: s.has_upstream,
ahead: s.ahead,
behind: s.behind,
unknown: s.unknown,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct JsonWorktree {
pub name: String,
pub id: String,
pub path: String,
pub branch: Option<String>,
pub head: Option<String>,
pub is_main: bool,
pub is_locked: bool,
pub is_prunable: bool,
pub status: JsonStatus,
pub age_seconds: Option<u64>,
pub issue: Option<u64>,
pub pr: Option<u64>,
}
impl From<&WorktreeInfo> for JsonWorktree {
fn from(w: &WorktreeInfo) -> Self {
Self {
name: w.name.clone(),
id: w.id.clone(),
path: w.path.to_string_lossy().into_owned(),
branch: w.branch.clone(),
head: w.head.clone(),
is_main: w.is_main,
is_locked: w.is_locked,
is_prunable: w.is_prunable,
status: JsonStatus::from(&w.status),
age_seconds: w.age.map(|d| d.as_secs()),
issue: w.link.issue,
pr: w.link.pr,
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct JsonPath {
pub name: String,
pub path: String,
pub branch: Option<String>,
}
impl From<&WorktreeInfo> for JsonPath {
fn from(w: &WorktreeInfo) -> Self {
Self {
name: w.name.clone(),
path: w.path.to_string_lossy().into_owned(),
branch: w.branch.clone(),
}
}
}
pub fn check_status_str(status: &CheckStatus) -> &'static str {
match status {
CheckStatus::Ok => "ok",
CheckStatus::Warning => "warning",
CheckStatus::Failed => "failed",
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct JsonCheck {
pub name: String,
pub status: String,
pub detail: String,
pub fix_hint: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize)]
pub struct JsonDoctorReport {
pub checks: Vec<JsonCheck>,
pub severity: String,
pub exit_code: i32,
}
impl From<&DoctorReport> for JsonDoctorReport {
fn from(r: &DoctorReport) -> Self {
Self {
checks: r
.checks
.iter()
.map(|c| JsonCheck {
name: c.name.clone(),
status: check_status_str(&c.status).to_string(),
detail: c.detail.clone(),
fix_hint: c.fix_hint.clone(),
})
.collect(),
severity: check_status_str(&r.severity()).to_string(),
exit_code: r.exit_code(),
}
}
}
pub fn worktrees(repo: &git2::Repository) -> Result<Vec<JsonWorktree>> {
Ok(worktree::list(repo)?.iter().map(JsonWorktree::from).collect())
}