Skip to main content

upstream_rs/providers/
release_provider.rs

1#![allow(async_fn_in_trait)]
2
3use std::path::Path;
4
5use anyhow::{Result, anyhow};
6use async_trait::async_trait;
7use chrono::{DateTime, Utc};
8
9use crate::models::provider::{Asset, Release, RepositorySearchFilters, RepositorySearchResult};
10
11#[async_trait(?Send)]
12pub trait ReleaseProvider {
13    async fn get_latest_release(&self, slug: &str) -> Result<Release>;
14
15    async fn get_releases(
16        &self,
17        slug: &str,
18        per_page: Option<u32>,
19        max_total: Option<u32>,
20    ) -> Result<Vec<Release>>;
21
22    async fn get_release_by_tag(&self, slug: &str, tag: &str) -> Result<Release>;
23
24    async fn get_branch_head_sha(&self, _slug: &str, _branch: &str) -> Result<String> {
25        Err(anyhow!("Branch builds are not supported for this provider"))
26    }
27
28    async fn search_repositories(
29        &self,
30        _query: &str,
31        _limit: Option<u32>,
32        _filters: &RepositorySearchFilters,
33    ) -> Result<Vec<RepositorySearchResult>> {
34        Err(anyhow!(
35            "Repository search is not supported for this provider"
36        ))
37    }
38
39    async fn get_latest_release_if_modified_since(
40        &self,
41        slug: &str,
42        _last_upgraded: Option<DateTime<Utc>>,
43    ) -> Result<Option<Release>> {
44        Ok(Some(self.get_latest_release(slug).await?))
45    }
46
47    async fn download_asset(
48        &self,
49        asset: &Asset,
50        destination_path: &Path,
51        dl_callback: Option<&mut (dyn FnMut(u64, u64) + '_)>,
52    ) -> Result<()>;
53}
54
55#[async_trait(?Send)]
56impl<T> ReleaseProvider for &T
57where
58    T: ReleaseProvider + ?Sized,
59{
60    async fn get_latest_release(&self, slug: &str) -> Result<Release> {
61        (*self).get_latest_release(slug).await
62    }
63
64    async fn get_releases(
65        &self,
66        slug: &str,
67        per_page: Option<u32>,
68        max_total: Option<u32>,
69    ) -> Result<Vec<Release>> {
70        (*self).get_releases(slug, per_page, max_total).await
71    }
72
73    async fn get_release_by_tag(&self, slug: &str, tag: &str) -> Result<Release> {
74        (*self).get_release_by_tag(slug, tag).await
75    }
76
77    async fn get_branch_head_sha(&self, slug: &str, branch: &str) -> Result<String> {
78        (*self).get_branch_head_sha(slug, branch).await
79    }
80
81    async fn search_repositories(
82        &self,
83        query: &str,
84        limit: Option<u32>,
85        filters: &RepositorySearchFilters,
86    ) -> Result<Vec<RepositorySearchResult>> {
87        (*self).search_repositories(query, limit, filters).await
88    }
89
90    async fn get_latest_release_if_modified_since(
91        &self,
92        slug: &str,
93        last_upgraded: Option<DateTime<Utc>>,
94    ) -> Result<Option<Release>> {
95        (*self)
96            .get_latest_release_if_modified_since(slug, last_upgraded)
97            .await
98    }
99
100    async fn download_asset(
101        &self,
102        asset: &Asset,
103        destination_path: &Path,
104        dl_callback: Option<&mut (dyn FnMut(u64, u64) + '_)>,
105    ) -> Result<()> {
106        (*self)
107            .download_asset(asset, destination_path, dl_callback)
108            .await
109    }
110}