1use std::error::Error;
2
3use keys_lib::{ApiKey, KeyValue};
4use reqwest::Client;
5use serde::Serialize;
6use url::Url;
7
8#[derive(Serialize)]
9struct SetValueBody<'a> {
10 value: &'a str,
11}
12
13pub struct KeysClient {
14 client: Client,
15 server_url: Url,
16 api_key: ApiKey,
17}
18
19impl KeysClient {
20 pub fn new<S: AsRef<str>>(server_url: S, api_key: ApiKey) -> Self {
21 let client = Client::default();
22 Self {
23 client,
24 server_url: Url::parse(server_url.as_ref()).expect("Invalid server URL"),
25 api_key,
26 }
27 }
28
29 pub async fn get_value<K: AsRef<str>>(&self, key: K) -> Result<KeyValue, Box<dyn Error>> {
30 let get_url = self
31 .server_url
32 .join(&format!("key_value/{}", key.as_ref()))?;
33
34 Ok(self
35 .client
36 .get(get_url)
37 .bearer_auth(self.api_key.to_base64())
38 .send()
39 .await?
40 .json()
41 .await?)
42 }
43
44 pub async fn set_value<K: AsRef<str>, V: AsRef<str>>(
45 &self,
46 key: K,
47 value: V,
48 ) -> Result<KeyValue, Box<dyn Error>> {
49 let set_url = self
50 .server_url
51 .join(&format!("key_value/{}", key.as_ref()))?;
52
53 Ok(self
54 .client
55 .post(set_url)
56 .bearer_auth(self.api_key.to_base64())
57 .body(
58 serde_json::to_string(&SetValueBody {
59 value: value.as_ref(),
60 })
61 .unwrap(),
62 )
63 .header("Content-Type", "application/json")
64 .send()
65 .await?
66 .json()
67 .await?)
68 }
69
70 pub async fn delete_value<K: AsRef<str>>(&self, key: K) -> Result<KeyValue, Box<dyn Error>> {
71 let delete_url = self
72 .server_url
73 .join(&format!("key_value/{}", key.as_ref()))?;
74
75 Ok(self
76 .client
77 .delete(delete_url)
78 .bearer_auth(self.api_key.to_base64())
79 .send()
80 .await?
81 .json()
82 .await?)
83 }
84}
85
86impl Default for KeysClient {
87 fn default() -> Self {
88 Self::new(
89 "https://api.keys.kent.software",
90 ApiKey::from_base64(
91 std::env::var("KEYS_API_KEY").expect("KEYS_API_KEY environment variable not set"),
92 )
93 .expect("Keys API key was invalid base64"),
94 )
95 }
96}