Skip to main content

objdiff_core/jobs/
check_update.rs

1use std::{sync::mpsc::Receiver, task::Waker};
2
3use anyhow::{Context, Result};
4use self_update::update::{Release, ReleaseUpdate};
5
6use crate::jobs::{Job, JobContext, JobResult, JobState, start_job, update_status};
7
8pub struct CheckUpdateConfig {
9    pub build_updater: fn() -> Result<Box<dyn ReleaseUpdate>>,
10    pub bin_names: Vec<String>,
11}
12
13pub struct CheckUpdateResult {
14    pub update_available: bool,
15    pub latest_release: Release,
16    pub found_binary: Option<String>,
17}
18
19fn run_check_update(
20    context: &JobContext,
21    cancel: Receiver<()>,
22    config: CheckUpdateConfig,
23) -> Result<Box<CheckUpdateResult>> {
24    update_status(context, "Fetching latest release".to_string(), 0, 1, &cancel)?;
25    let updater = (config.build_updater)().context("Failed to create release updater")?;
26    let releases = updater.get_latest_release()?;
27    let update_available = releases.is_update_available()?;
28    let latest_release = releases.latest().context("No release found")?.clone();
29    // Find the binary name in the release assets
30    let mut found_binary = None;
31    for bin_name in &config.bin_names {
32        if latest_release.assets().iter().any(|a| a.name() == bin_name) {
33            found_binary = Some(bin_name.clone());
34            break;
35        }
36    }
37
38    update_status(context, "Complete".to_string(), 1, 1, &cancel)?;
39    Ok(Box::new(CheckUpdateResult { update_available, latest_release, found_binary }))
40}
41
42pub fn start_check_update(waker: Waker, config: CheckUpdateConfig) -> JobState {
43    start_job(waker, "Check for updates", Job::CheckUpdate, move |context, cancel| {
44        run_check_update(&context, cancel, config)
45            .map(|result| JobResult::CheckUpdate(Some(result)))
46    })
47}