use std::collections::HashMap;
use std::convert::From;
use std::sync::Arc;
use color_eyre::Result;
use crate::config::tracker;
use crate::config::TicketQuery;
use crate::ticket_abstraction::IntoAbstract;
pub struct ReferenceQueries(pub Vec<Arc<TicketQuery>>);
impl From<&[Arc<TicketQuery>]> for ReferenceQueries {
fn from(item: &[Arc<TicketQuery>]) -> Self {
let mut reference_queries: Vec<Arc<TicketQuery>> = Vec::new();
for query in item {
if !query.references.is_empty() {
log::info!(
"Query {:?} has {} reference(s)",
query.using,
query.references.len()
);
for reference in &query.references {
log::info!(" Reference: {:?}", reference.using);
reference_queries.push(Arc::clone(reference));
}
}
}
log::info!("Total reference queries extracted: {}", reference_queries.len());
Self(reference_queries)
}
}
pub struct ReferenceSignatures(HashMap<Arc<TicketQuery>, Vec<String>>);
impl ReferenceSignatures {
pub fn new<T: IntoAbstract, U: IntoAbstract>(
ref_bugs: Vec<(Arc<TicketQuery>, T)>,
ref_issues: Vec<(Arc<TicketQuery>, U)>,
config: &tracker::Config,
) -> Result<Self> {
let mut signatures: HashMap<Arc<TicketQuery>, Vec<String>> = HashMap::new();
Self::store(&mut signatures, ref_bugs, config)?;
Self::store(&mut signatures, ref_issues, config)?;
for references in signatures.values_mut() {
references.sort_unstable();
}
Ok(Self(signatures))
}
fn store<T: IntoAbstract>(
signatures: &mut HashMap<Arc<TicketQuery>, Vec<String>>,
ref_issues: Vec<(Arc<TicketQuery>, T)>,
config: &tracker::Config,
) -> Result<()> {
for (query, issue) in ref_issues {
let ticket = issue.into_abstract(None, config)?;
signatures
.entry(query)
.and_modify(|e| e.push(ticket.signature(false)))
.or_insert_with(|| vec![ticket.signature(false)]);
}
Ok(())
}
pub fn reattach_to(&self, main_query: &Arc<TicketQuery>) -> Vec<String> {
let needed_references = &main_query.references;
self.0
.iter()
.filter(|(query, _references)| needed_references.contains(query))
.flat_map(|(_query, references)| references)
.cloned()
.collect()
}
}