upstream_rs/providers/
release_provider.rs1#![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}