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
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
use anyhow::Result;
use serde::{Deserialize, Serialize};

pub struct Client {}
pub struct Bucket {
    name: String,
}

impl Client {
    pub fn new() -> Client {
        Client {}
    }
    pub fn bucket(&self, name: &str) -> Bucket {
        Bucket {
            name: name.to_string(),
        }
    }
}

impl Bucket {
    pub async fn list(&self) -> Result<Objects> {
        let url = format!(
            "https://storage.googleapis.com/storage/v1/b/{}/o",
            self.name
        );
        let access_token = google_auth::DefaultCredentials::new()
            .token()
            .await?
            .access_token;
        let client = reqwest::Client::new();
        let res = client
            .get(&url)
            .header(
                reqwest::header::AUTHORIZATION,
                format!("Bearer {}", access_token),
            )
            .header(reqwest::header::ACCEPT, "application/json")
            .send()
            .await?;
        let text = res.text().await?;
        let objects: Objects = serde_json::from_str(&text)?;
        Ok(objects)
    }

    pub async fn insert(&self, data: Vec<u8>, file_name: &str) -> Result<Object> {
        let url = format!(
            "https://storage.googleapis.com/upload/storage/v1/b/{}/o?uploadType=media&name={}",
            self.name, file_name
        );
        let access_token = google_auth::DefaultCredentials::new()
            .token()
            .await?
            .access_token;
        let client = reqwest::Client::new();
        let len = data.len();
        let res = client
            .post(&url)
            .body(data)
            .header(
                reqwest::header::AUTHORIZATION,
                format!("Bearer {}", access_token),
            )
            .header(reqwest::header::CONTENT_LENGTH, len)
            .header(
                reqwest::header::CONTENT_TYPE,
                "application/json;charset=UTF-8",
            )
            .send()
            .await?;
        let object: Object = res.json().await?;
        Ok(object)
    }
}

#[derive(Deserialize, Serialize, Debug)]
pub struct Objects {
    kind: String,
    items: Vec<Object>,
}

#[derive(Deserialize, Serialize, Debug)]
#[serde(rename_all = "camelCase")]
pub struct Object {
    kind: String,
    id: String,
    self_link: String,
    media_link: String,
    name: String,
    bucket: String,
    generation: String,
    metageneration: String,
    content_type: Option<String>,
    storage_class: String,
    size: String,
    md5_hash: String,
    crc32c: String,
    etag: String,
    time_created: String,
    updated: String,
    time_storage_class_updated: String,
}