1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
/*! Git database

The Git Database API gives you access to read and write raw Git objects to your Git database on GitHub and to list and update your references (branch heads and tags). For more information about using the Git Database API, see "Getting started with the Git data API."

!*/

use crate::GithubClient;
use anyhow::{bail, Result};
use async_trait::async_trait;
use jacklog::{debug, trace};
use reqwest::header::LINK;
use serde::{Deserialize, Serialize};

#[derive(Default, Debug)]
pub struct GetBlobRequest {
    pub owner: String,
    pub repo: String,
    pub file_sha: String,
}

#[derive(Debug, Default, Deserialize)]
pub struct GetBlobResponse {
    content: String,
    encoding: String,
    sha: String,
    size: u64,
}

#[async_trait]
pub trait Git {
    async fn get_blob(&self, input: GetBlobRequest) -> Result<GetBlobResponse>;
}

#[async_trait]
impl Git for GithubClient {
    /*!
    A Git blob (binary large object) is the object type used to store the contents of each file in a repository. The file's SHA-1 hash is computed and stored in the blob object. These endpoints allow you to read and write blob objects to your Git database on GitHub. Blobs leverage these custom media types. You can read more about the use of media types in the API here.use crate::{GithubClient, SortDirection, User};

        Get the contents of a file at a given commit.
    !*/
    async fn get_blob(&self, input: GetBlobRequest) -> Result<GetBlobResponse> {
        // Make the request.
        let res = self
            .client()
            .get(&format!(
                "https://api.github.com/repos/{}/{}/git/blobs/{}",
                input.owner, input.repo, input.file_sha,
            ))
            .send()
            .await?;

        // Check the response code.
        if !res.status().is_success() {
            bail!("{}", res.status().canonical_reason().unwrap_or(&"unknown"));
        }

        Ok(res.json().await?)
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::EnvironmentProvider;
    use crate::{org, repo};

    #[tokio::test]
    async fn test_get_blob() {
        let client = GithubClient::new(&EnvironmentProvider::default()).unwrap();
        let res = client
            .get_blob(GetBlobRequest {
                owner: org(),
                repo: repo(),
                file_sha: "9dabfec9194affdefddeffab8a74ec018554bf56".into(),
            })
            .await
            .unwrap();

        // Check response.
        let actual = base64::decode(&res.content.trim()).unwrap();
        assert_eq!(actual, "foobaz\n".as_bytes());
        assert_eq!(
            res.sha,
            "9dabfec9194affdefddeffab8a74ec018554bf56".to_string()
        );
        assert_eq!(res.size, 7);
    }
}