1use std::future::Future;
7
8use anyhow::Result;
9
10#[derive(Debug, Default, Clone)]
11pub struct PinUpdateOutcome {
12 pub previous_unpin_error: Option<String>,
13}
14
15pub async fn pin_update_add_rm<FAdd, FRm, FutAdd, FutRm>(
16 old_cid: Option<&str>,
17 new_cid: &str,
18 pin_name: &str,
19 add_named: FAdd,
20 remove_pin: FRm,
21) -> Result<PinUpdateOutcome>
22where
23 FAdd: Fn(String, String) -> FutAdd,
24 FRm: Fn(String) -> FutRm,
25 FutAdd: Future<Output = Result<()>>,
26 FutRm: Future<Output = Result<()>>,
27{
28 let Some(previous) = old_cid else {
29 add_named(new_cid.to_string(), pin_name.to_string()).await?;
30 return Ok(PinUpdateOutcome::default());
31 };
32
33 if previous == new_cid {
34 return Ok(PinUpdateOutcome::default());
35 }
36
37 add_named(new_cid.to_string(), pin_name.to_string()).await?;
38
39 let previous_unpin_error = remove_pin(previous.to_string())
40 .await
41 .err()
42 .map(|err| err.to_string());
43
44 Ok(PinUpdateOutcome {
45 previous_unpin_error,
46 })
47}