librelink_client/
client.rs1use reqwest::Client;
2
3use crate::{
4 connection::{ConnectionGraphResponse, ResponseConnections},
5 glucose::{GlucoseHistoryRequest, LogBookRequest},
6 login::try_get_access_token,
7};
8
9pub struct LibreLinkClient {
10 client: Client,
11 token: String,
12 base_url: Option<String>,
13 region: Option<String>,
14}
15
16pub struct Credentials {
17 pub username: String,
18 pub password: String,
19}
20
21impl LibreLinkClient {
22 pub async fn new(credentials: Credentials, region: Option<String>) -> Result<Self, Box<dyn std::error::Error>> {
23 let token = try_get_access_token(&credentials.username, &credentials.password).await;
24
25 match token {
26 Ok(token) => {
27 let mut client = LibreLinkClient {
28 client: Client::new(),
29 token,
30 region,
31 base_url: None
32 };
33 client.set_base_url();
34 Ok(client)
35 }
36 Err(e) => Err(e),
37 }
38 }
39
40 pub fn from_token(token: String, region: Option<String>) -> Self {
41 let mut client = LibreLinkClient {
42 client: Client::new(),
43 token,
44 region,
45 base_url: None
46 };
47 client.set_base_url();
48 client
49 }
50
51
52 fn set_base_url(&mut self) {
53 if let Some(region) = &self.region {
55 let url = format!("https://api-{}.libreview.io", region);
56 self.base_url = Some(url);
57 } else {
58 let url = "https://api.libreview.io".to_string();
59 self.base_url = Some(url);
60 }
61 }
62
63 pub async fn get_connections(&self) -> Result<ResponseConnections, Box<dyn std::error::Error>> {
64 let base_url = self.base_url.clone().unwrap();
65 let url = format!("{}/{}", &base_url, "llu/connections");
66
67 let response = self
68 .client
69 .get(url)
70 .header("version", "4.7.1")
71 .header("product", "llu.android")
72 .header("User-Agent", "Apidog/1.0.0 (https://apidog.com)")
73 .bearer_auth(&self.token)
74 .send()
75 .await?;
76
77 let api_response: Result<ResponseConnections, reqwest::Error> = response.json().await;
78
79 match api_response {
80 Ok(response_data) => Ok(response_data),
81 Err(e) => Err(Box::new(e)),
82 }
83 }
84
85 pub async fn get_connection_graph(
86 &self,
87 connection_id: &str,
88 ) -> Result<ConnectionGraphResponse, Box<dyn std::error::Error>> {
89 let base_url = self.base_url.clone().unwrap();
90 let url = format!(
91 "{}/{}/{}/{}",
92 &base_url, "llu/connections", connection_id, "graph"
93 );
94
95 let response = self
96 .client
97 .get(url)
98 .header("version", "4.7.1")
99 .header("product", "llu.android")
100 .header("User-Agent", "Apidog/1.0.0 (https://apidog.com)")
101 .bearer_auth(&self.token)
102 .send()
103 .await?;
104
105 let api_response: Result<ConnectionGraphResponse, reqwest::Error> = response.json().await;
106
107 match api_response {
108 Ok(response_data) => Ok(response_data),
109 Err(e) => Err(Box::new(e)),
110 }
111 }
112
113 pub async fn get_glucose_history(
114 &self,
115 num_periods: i32,
116 period: i32,
117 ) -> Result<GlucoseHistoryRequest, Box<dyn std::error::Error>> {
118 let base_url = self.base_url.clone().unwrap();
119 let url = format!(
120 "{}/{}?numPeriods={}&period={}",
121 &base_url, "glucoseHistory", num_periods, period
122 );
123
124 let response = self
125 .client
126 .get(url)
127 .header("User-Agent", "Apidog/1.0.0 (https://apidog.com)")
128 .bearer_auth(&self.token)
129 .send()
130 .await?;
131
132 let api_response: Result<GlucoseHistoryRequest, reqwest::Error> = response.json().await;
133
134 match api_response {
135 Ok(response_data) => Ok(response_data),
136 Err(e) => Err(Box::new(e)),
137 }
138 }
139
140 pub async fn get_log_book(
141 &self,
142 connection_id: &str,
143 ) -> Result<LogBookRequest, Box<dyn std::error::Error>> {
144 let base_url = self.base_url.clone().unwrap();
145 let url = format!(
146 "{}/{}/{}/{}",
147 &base_url, "llu/connections", connection_id, "logbook"
148 );
149
150 let response = self
151 .client
152 .get(url)
153 .header("version", "4.7.1")
154 .header("product", "llu.android")
155 .header("User-Agent", "Apidog/1.0.0 (https://apidog.com)")
156 .bearer_auth(&self.token)
157 .send()
158 .await?;
159
160 let api_response: Result<LogBookRequest, reqwest::Error> = response.json().await;
161
162 match api_response {
163 Ok(response_data) => Ok(response_data),
164 Err(e) => Err(Box::new(e)),
165 }
166 }
167}