| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
use crate::db::{self, issues as idb, proposals as pdb}; |
| 6 |
use crate::render::refs; |
| 7 |
use crate::Shared; |
| 8 |
|
| 9 |
|
| 10 |
#[derive(Clone, Debug)] |
| 11 |
pub struct Link { |
| 12 |
|
| 13 |
pub kind: &'static str, |
| 14 |
pub number: i64, |
| 15 |
pub title: String, |
| 16 |
|
| 17 |
pub state: String, |
| 18 |
pub url: String, |
| 19 |
} |
| 20 |
|
| 21 |
|
| 22 |
pub async fn issues_closed_by(app: &Shared, row: &db::repos::RepoRow, texts: &[&str]) -> Vec<Link> { |
| 23 |
let mut numbers: Vec<i64> = texts.iter().flat_map(|t| refs::closes(t)).collect(); |
| 24 |
numbers.sort(); |
| 25 |
numbers.dedup(); |
| 26 |
let mut out = Vec::new(); |
| 27 |
for n in numbers { |
| 28 |
if let Ok(Some(i)) = idb::get(&app.db, row.id, n).await { |
| 29 |
out.push(Link { kind: "issue", number: n, title: i.title, state: i.state, url: format!("/{}/issue/{n}", row.slug()) }); |
| 30 |
} |
| 31 |
} |
| 32 |
out |
| 33 |
} |
| 34 |
|
| 35 |
|
| 36 |
|
| 37 |
pub async fn proposals_closing(app: &Shared, row: &db::repos::RepoRow, n: i64) -> Vec<Link> { |
| 38 |
let all = pdb::list(&app.db, row.id, &["draft", "open", "landed", "closed"]).await.unwrap_or_default(); |
| 39 |
|
| 40 |
let hashes: Vec<Vec<String>> = all.iter().map(|p| p.projected_changes()).collect(); |
| 41 |
let messages: Vec<Vec<String>> = match crate::repos::RepoName::new(&row.owner, &row.name) { |
| 42 |
Some(name) => { |
| 43 |
let wanted = hashes.clone(); |
| 44 |
app.repos |
| 45 |
.read(&name, move |r, _| { |
| 46 |
Ok(wanted |
| 47 |
.iter() |
| 48 |
.map(|hs| { |
| 49 |
hs.iter() |
| 50 |
.filter_map(|h| oxy_core::hash::ChangeHash::from_hex(h)) |
| 51 |
.filter_map(|h| r.store().get_change_meta(&h).ok().map(|c| c.message)) |
| 52 |
.collect() |
| 53 |
}) |
| 54 |
.collect()) |
| 55 |
}) |
| 56 |
.await |
| 57 |
.unwrap_or_else(|_| vec![vec![]; hashes.len()]) |
| 58 |
} |
| 59 |
None => vec![vec![]; hashes.len()], |
| 60 |
}; |
| 61 |
all.into_iter() |
| 62 |
.zip(messages) |
| 63 |
.filter(|(p, msgs)| { |
| 64 |
refs::closes(&p.body).contains(&n) || refs::closes(&p.title).contains(&n) || msgs.iter().any(|m| refs::closes(m).contains(&n)) |
| 65 |
}) |
| 66 |
.map(|(p, _)| Link { |
| 67 |
kind: "proposal", |
| 68 |
number: p.number, |
| 69 |
url: format!("/{}/proposal/{}", row.slug(), p.number), |
| 70 |
title: p.title, |
| 71 |
state: p.state, |
| 72 |
}) |
| 73 |
.collect() |
| 74 |
} |