use crate::db::GraphDb;
use crate::repograph::context::{context_with, ContextOptions, ContextReport};
use crate::repograph::impact::{impact, ImpactOptions, ImpactReport};
use crate::repograph::owners::{owners, OwnersReport};
use crate::repograph::render::sanitize;
use core_storage::fs::Fs;
use serde::Serialize;
use std::collections::BTreeSet;
use std::path::Path;
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize)]
#[serde(rename_all = "snake_case")]
pub enum Depth {
Context,
Impact,
History,
All,
}
impl Depth {
#[must_use]
pub fn parse(s: &str) -> Option<Depth> {
match s {
"context" => Some(Depth::Context),
"impact" => Some(Depth::Impact),
"history" => Some(Depth::History),
"all" => Some(Depth::All),
_ => None,
}
}
pub const NAMES: [&'static str; 4] = ["context", "impact", "history", "all"];
fn wants_impact(self) -> bool {
matches!(self, Depth::Impact | Depth::All)
}
fn wants_history(self) -> bool {
matches!(self, Depth::History | Depth::All)
}
}
#[derive(Debug, Clone, PartialEq, Serialize)]
pub struct ExploreReport {
pub target: String,
pub depth: Depth,
pub context: ContextReport,
pub impact: Option<ImpactReport>,
pub owners: Option<OwnersReport>,
pub partners: Vec<(String, f64)>,
}
#[must_use]
pub fn explore<F: Fs>(
db: &GraphDb<F>,
repo: Option<&Path>,
target: &str,
depth: Depth,
full: bool,
) -> ExploreReport {
let context = context_with(db, repo, target, &ContextOptions { source: full });
let mut report = ExploreReport {
target: sanitize(target),
depth,
context,
impact: None,
owners: None,
partners: Vec::new(),
};
let file = report.context.file.clone();
if file.is_empty() {
return report;
}
if depth.wants_impact() {
report.impact = Some(impact(
db,
std::slice::from_ref(&file),
&BTreeSet::new(),
&ImpactOptions::default(),
));
}
if depth.wants_history() {
report.owners = owners(db, &file, None);
report.partners = report.context.partners.clone();
}
report
}