gh_stack/
persist.rs

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}