remoteit_api/
api_async.rs1use crate::auth::{build_auth_header, get_date};
8use crate::operations::{cancel_job, delete_file, delete_file_version, get_application_types, get_devices, get_files, get_jobs, get_owned_organization, start_job, CancelJob, DeleteFile, DeleteFileVersion, DeviceState, GetApplicationTypes, GetDevices, GetFiles, GetJobs, GetOwnedOrganization, StartJob};
9use crate::{R3Client, BASE_URL, GRAPHQL_PATH};
10use bon::bon;
11use graphql_client::{GraphQLQuery, QueryBody, Response};
12use reqwest::Client;
13use reqwest::Method;
14use serde::{Deserialize, Serialize};
15use std::error::Error;
16
17#[bon]
18impl R3Client {
19 pub async fn send_remoteit_graphql_request_async<V: Serialize, R: for<'a> Deserialize<'a>>(
27 &self,
28 query_body: &QueryBody<V>,
29 ) -> Result<Response<R>, Box<dyn Error>> {
30 let date = get_date();
31 let auth_header = build_auth_header()
32 .key_id(self.credentials.access_key_id())
33 .key(self.credentials.key())
34 .content_type("application/json")
35 .method(&Method::POST)
36 .path(GRAPHQL_PATH)
37 .date(&date)
38 .call();
39 let client = Client::new();
40 let response = client
41 .post(format!("{BASE_URL}{GRAPHQL_PATH}"))
42 .header("Date", date)
43 .header("Content-Type", "application/json")
44 .header("Authorization", auth_header)
45 .json(&query_body)
46 .send()
47 .await?;
48 let response: Response<R> = response.json().await?;
49 Ok(response)
50 }
51
52 #[builder]
56 pub async fn get_files_async(
57 &self,
58 org_id: Option<String>,
60 ) -> Result<Response<get_files::ResponseData>, Box<dyn Error>> {
61 let request_body = GetFiles::build_query(get_files::Variables { org_id });
62 self.send_remoteit_graphql_request_async(&request_body)
63 .await
64 }
65
66 #[builder]
68 pub async fn delete_file_async(
69 &self,
70 file_id: String,
73 ) -> Result<Response<delete_file::ResponseData>, Box<dyn Error>> {
74 let request_body = DeleteFile::build_query(delete_file::Variables { file_id });
75 self.send_remoteit_graphql_request_async(&request_body)
76 .await
77 }
78
79 #[builder]
81 pub async fn delete_file_version_async(
82 &self,
83 file_version_id: String,
86 ) -> Result<Response<delete_file_version::ResponseData>, Box<dyn Error>> {
87 let request_body =
88 DeleteFileVersion::build_query(delete_file_version::Variables { file_version_id });
89 self.send_remoteit_graphql_request_async(&request_body)
90 .await
91 }
92
93 #[builder]
95 pub async fn start_job_async(
96 &self,
97 file_id: String,
101 device_ids: Vec<String>,
104 #[builder(default)]
108 arguments: Vec<start_job::ArgumentInput>,
109 ) -> Result<Response<start_job::ResponseData>, Box<dyn Error>> {
110 let request_body = StartJob::build_query(start_job::Variables {
111 file_id,
112 device_ids,
113 arguments,
114 });
115 self.send_remoteit_graphql_request_async(&request_body)
116 .await
117 }
118
119 #[builder]
121 pub async fn cancel_job_async(
122 &self,
123 job_id: String,
126 ) -> Result<Response<cancel_job::ResponseData>, Box<dyn Error>> {
127 let request_body = CancelJob::build_query(cancel_job::Variables { job_id });
128 self.send_remoteit_graphql_request_async(&request_body)
129 .await
130 }
131
132 #[builder]
134 pub async fn get_jobs_async(
135 &self,
136 org_id: Option<String>,
138 limit: Option<i64>,
140 job_id_filter: Option<Vec<String>>,
142 status_filter: Option<Vec<get_jobs::JobStatusEnum>>,
144 ) -> Result<Response<get_jobs::ResponseData>, Box<dyn Error>> {
145 let request_body = GetJobs::build_query(get_jobs::Variables {
146 org_id,
147 limit,
148 job_ids: job_id_filter,
149 statuses: status_filter,
150 });
151 self.send_remoteit_graphql_request_async(&request_body)
152 .await
153 }
154
155 #[builder]
163 pub async fn get_owned_organization_async(
164 &self,
165 ) -> Result<Response<get_owned_organization::ResponseData>, Box<dyn Error>> {
166 let request_body = GetOwnedOrganization::build_query(get_owned_organization::Variables {});
167 self.send_remoteit_graphql_request_async(&request_body)
168 .await
169 }
170 #[builder]
175 pub async fn get_application_types_async(
176 &self,
177 ) -> Result<Response<get_application_types::ResponseData>, Box<dyn Error>> {
178 let request_body = GetApplicationTypes::build_query(get_application_types::Variables {});
179 self.send_remoteit_graphql_request_async(&request_body)
180 .await
181 }
182
183 #[builder]
185 pub async fn get_devices_async(
186 &self,
187 org_id: Option<String>,
189 limit: Option<i64>,
191 offset: Option<i64>,
193 state: Option<DeviceState>
195 ) -> Result<Response<get_devices::ResponseData>, Box<dyn Error>> {
196 let request_body = GetDevices::build_query(get_devices::Variables {
197 org_id,
198 limit,
199 offset,
200 state: state.map(|s| s.to_string()),
201 });
202 self.send_remoteit_graphql_request_async(&request_body)
203 .await
204 }
205
206 }
208
209#[cfg(test)]
210mod tests {
211 use super::*;
212 use crate::credentials::Credentials;
213 use std::path::PathBuf;
214
215 fn get_credentials() -> Credentials {
216 Credentials::load_from_disk()
217 .custom_credentials_path(PathBuf::from(".env.remoteit"))
218 .call()
219 .unwrap()
220 .take_profile("default")
221 .unwrap()
222 .unwrap()
223 }
224
225 fn get_client() -> R3Client {
226 R3Client::builder().credentials(get_credentials()).build()
227 }
228
229 #[tokio::test]
230 async fn test_get_files_async() {
231 let response = get_client().get_files_async().call().await.unwrap();
232 assert!(response.data.is_some());
233 assert!(response.errors.is_none());
234 }
235
236 #[tokio::test]
237 async fn test_get_jobs_async() {
238 let response = get_client().get_jobs_async().limit(1).call().await.unwrap();
239 assert!(response.data.is_some());
240 assert!(response.errors.is_none());
241 }
242
243 #[tokio::test]
244 async fn test_get_jobs_with_filters_async() {
245 let response = get_client()
246 .get_jobs_async()
247 .job_id_filter(vec!["foobar".to_string()])
248 .status_filter(vec![get_jobs::JobStatusEnum::SUCCESS])
249 .call()
250 .await
251 .unwrap();
252 assert!(response.data.is_some());
253 assert!(response.errors.is_none());
254 }
255
256 #[tokio::test]
257 async fn test_get_application_types_async() {
258 let response = get_client()
259 .get_application_types_async()
260 .call()
261 .await
262 .unwrap();
263 assert!(response.data.is_some());
264 assert!(response.errors.is_none());
265 }
266
267 #[tokio::test]
268 async fn test_get_devices_async() {
269 let response = get_client().get_devices_async().call().await.unwrap();
270 assert!(response.data.is_some());
271 assert!(response.errors.is_none());
272 }
273}