google_wallet/
drive_api.rs1use reqwest::Client;
2use serde::{Deserialize, Serialize};
3use std::error::Error;
4
5const BASE_URL: &str = "https://www.googleapis.com/drive/v3";
6
7#[derive(Debug, Clone)]
8pub struct DriveApi {
9 client: Client,
10 access_token: String,
11}
12
13impl DriveApi {
14 pub fn new(access_token: String) -> Self {
16 DriveApi {
17 client: Client::new(),
18 access_token,
19 }
20 }
21
22 pub async fn list_files(&self) -> Result<Vec<File>, Box<dyn Error>> {
24 let url = format!("{}/files", BASE_URL);
25
26 let response = self
27 .client
28 .get(&url)
29 .bearer_auth(&self.access_token)
30 .query(&[("spaces", "appDataFolder")]) .send()
32 .await?;
33
34 if response.status().is_success() {
35 let file_list: FileList = response.json().await?;
36 Ok(file_list.files)
37 } else {
38 let error_msg = response.text().await?;
39 Err(format!("Error listing files: {}", error_msg).into())
40 }
41 }
42
43 pub async fn upload_file(&self, content: &str) -> Result<File, Box<dyn Error>> {
45 tracing::debug!("Uploading file to Google Drive: {content}");
46 let metadata = serde_json::json!({
47 "name": option_env!("ENV").unwrap_or("local"),
48 "parents": ["appDataFolder"]
49 });
50
51 let url = format!("https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart");
52
53 let form = reqwest::multipart::Form::new()
54 .part(
55 "metadata",
56 reqwest::multipart::Part::text(metadata.to_string())
57 .mime_str("application/json")?, )
59 .part(
60 "file",
61 reqwest::multipart::Part::text(content.to_string()).mime_str("text/plain")?,
62 );
63 let response = self
64 .client
65 .post(&url)
66 .bearer_auth(&self.access_token)
67 .multipart(form)
68 .send()
69 .await?;
70
71 if response.status().is_success() {
72 let uploaded_file: File = response.json().await?;
73 Ok(uploaded_file)
74 } else {
75 let error_msg = response.text().await?;
76 Err(format!("Error uploading file: {}", error_msg).into())
77 }
78 }
79
80 pub async fn get_file(&self, file_id: &str) -> Result<String, Box<dyn Error>> {
81 let url = format!("{}/files/{}?alt=media", BASE_URL, file_id);
82
83 let response = self
84 .client
85 .get(&url)
86 .bearer_auth(&self.access_token)
87 .send()
88 .await?;
89
90 if response.status().is_success() {
91 let contents = response.text().await?;
92 Ok(contents)
93 } else {
94 let error_msg = response.text().await?;
95 Err(format!("Error getting file: {}", error_msg).into())
96 }
97 }
98}
99
100#[derive(Debug, Deserialize)]
101pub struct FileList {
102 pub files: Vec<File>,
103}
104
105#[derive(Debug, Serialize, Deserialize)]
106pub struct File {
107 pub id: String,
108 pub name: String,
109}