1use futures::future::join_all;
2use regex::Regex;
3use std::error::Error;
4
5use crate::api::pull_request;
6use crate::graph::FlatDep;
7use crate::Credentials;
8
9const SHIELD_OPEN: &str = "<!---GHSTACKOPEN-->";
10const SHIELD_CLOSE: &str = "<!---GHSTACKCLOSE-->";
11
12fn safe_replace(body: &str, table: &str) -> String {
13 let new = format!("\n{}\n{}\n{}\n", SHIELD_OPEN, table, SHIELD_CLOSE);
14
15 if body.contains(SHIELD_OPEN) {
16 let matcher = format!(
17 "(?s){}.*{}",
18 regex::escape(SHIELD_OPEN),
19 regex::escape(SHIELD_CLOSE)
20 );
21 let re = Regex::new(&matcher).unwrap();
22 re.replace_all(body, &new[..]).into_owned()
23 } else {
24 let mut body: String = body.to_owned();
25 body.push_str(&new);
26 body
27 }
28}
29
30pub async fn persist(
31 prs: &FlatDep,
32 table: &str,
33 c: &Credentials,
34) -> Result<(), Box<dyn Error>> {
35 let futures = prs.iter().map(|(pr, _)| {
36 let description = safe_replace(pr.body(), table);
37 pull_request::update_description(description, pr.clone(), c)
38 });
39
40 let results = join_all(futures.collect::<Vec<_>>()).await;
41
42 for result in results {
43 result.unwrap();
44 }
45
46 Ok(())
47}