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, }