#[allow(clippy::wildcard_imports)]
use super::*;
pub(super) fn group_value(issue: &Issue, group: &str) -> String {
let values = match group {
"cycle" => issue.cycles.as_ref(),
"milestone" => issue.milestones.as_ref(),
_ => None,
};
values
.and_then(|values| values.first().cloned())
.unwrap_or_else(|| "(none)".to_string())
}
pub(super) fn group_key(
issue: &Issue,
group: &str,
project_groups: Option<&BTreeMap<u32, String>>,
epic_groups: Option<&BTreeMap<u32, String>>,
) -> String {
match group {
"project" => project_groups
.and_then(|groups| groups.get(&issue.number).cloned())
.unwrap_or_else(|| crate::projects::NO_PROJECT_BUCKET.to_string()),
"epic" => epic_groups
.and_then(|groups| groups.get(&issue.number).cloned())
.unwrap_or_else(|| crate::search::NO_EPIC_BUCKET.to_string()),
_ => group_value(issue, group),
}
}
pub(super) fn project_group_labels(store: &Store, issues: &[Issue]) -> BTreeMap<u32, String> {
let index = crate::projects::ProjectIndex::build(&store.config, issues);
let memberships = index.resolved_memberships();
issues
.iter()
.map(|issue| {
let ids = memberships.get(&issue.number).cloned().unwrap_or_default();
(issue.number, crate::projects::project_bucket_label(&ids))
})
.collect()
}
pub(super) fn epic_group_labels(store: &Store, issues: &[Issue]) -> BTreeMap<u32, String> {
let memberships = crate::epics::memberships_by_issue(&store.config, issues);
issues
.iter()
.map(|issue| {
let ids = memberships.get(&issue.number).cloned().unwrap_or_default();
(issue.number, crate::search::epic_bucket_label(&ids))
})
.collect()
}
pub(super) fn sort_by_project(store: &Store, issues: &mut [Issue], groups: &BTreeMap<u32, String>) {
let declaration: Vec<&str> = store.config.projects.keys().map(String::as_str).collect();
let rank = |issue: &Issue| -> usize {
match groups.get(&issue.number).map(String::as_str) {
Some(crate::projects::MULTIPLE_PROJECTS_BUCKET) => usize::MAX - 1,
Some(crate::projects::NO_PROJECT_BUCKET) | None => usize::MAX,
Some(id) => declaration
.iter()
.position(|candidate| *candidate == id)
.unwrap_or(usize::MAX),
}
};
issues.sort_by(|a, b| rank(a).cmp(&rank(b)).then(a.number.cmp(&b.number)));
}
pub(super) fn sort_by_epic(store: &Store, issues: &mut [Issue], groups: &BTreeMap<u32, String>) {
let declaration: Vec<&str> = store.config.epics.keys().map(String::as_str).collect();
let rank = |issue: &Issue| -> usize {
match groups.get(&issue.number).map(String::as_str) {
Some(crate::search::MULTIPLE_EPICS_BUCKET) => usize::MAX - 1,
Some(crate::search::NO_EPIC_BUCKET) | None => usize::MAX,
Some(id) => declaration
.iter()
.position(|candidate| *candidate == id)
.unwrap_or(usize::MAX),
}
};
issues.sort_by(|a, b| rank(a).cmp(&rank(b)).then(a.number.cmp(&b.number)));
}