1use crate::http::HttpClient;
2use anyhow::{Context, Result};
3use futures::AsyncReadExt;
4use serde::Deserialize;
5use std::sync::Arc;
6
7pub struct GitHubLspBinaryVersion {
8 pub name: String,
9 pub url: String,
10}
11
12#[derive(Deserialize, Debug)]
13pub struct GithubRelease {
14 pub name: String,
15 pub assets: Vec<GithubReleaseAsset>,
16}
17
18#[derive(Deserialize, Debug)]
19pub struct GithubReleaseAsset {
20 pub name: String,
21 pub browser_download_url: String,
22}
23
24pub async fn latest_github_release(
25 repo_name_with_owner: &str,
26 http: Arc<dyn HttpClient>,
27) -> Result<GithubRelease, anyhow::Error> {
28 let mut response = http
29 .get(
30 &format!("https://api.github.com/repos/{repo_name_with_owner}/releases/latest"),
31 Default::default(),
32 true,
33 )
34 .await
35 .context("error fetching latest release")?;
36 let mut body = Vec::new();
37 response
38 .body_mut()
39 .read_to_end(&mut body)
40 .await
41 .context("error reading latest release")?;
42
43 let release = serde_json::from_slice::<GithubRelease>(body.as_slice());
44 if release.is_err() {
45 log::error!(
46 "Github API response text: {:?}",
47 String::from_utf8_lossy(body.as_slice())
48 );
49 }
50
51 release.context("error deserializing latest release")
52}