hyperdb_rs/
lib.rs

1//!
2//!
3//! HyperDB Rust Client
4//!
5//! Author: [Afaan Bilal](https://afaan.dev)
6//!
7//! Source: [GitHub](https://github.com/AfaanBilal/hyperdb-rs)
8//!
9use core::panic;
10use reqwest::{blocking::Client, Method, Result};
11
12pub const R_OK: &str = "OK";
13pub const R_TRUE: &str = "YES";
14const R_PONG: &str = "PONG";
15const R_INVALID_CREDENTIALS: &str = "INVALID_CREDENTIALS";
16const R_AUTH_FAILED: &str = "AUTH_FAILED";
17
18pub struct HyperClient {
19    address: String,
20    username: String,
21    password: String,
22    auth_enabled: bool,
23    token: String,
24    client: Option<Client>,
25}
26
27impl HyperClient {
28    pub fn new(address: String) -> HyperClient {
29        let mut hc = HyperClient {
30            address,
31            username: String::from(""),
32            password: String::from(""),
33            auth_enabled: false,
34            token: String::from(""),
35            client: None,
36        };
37
38        hc.connect();
39
40        hc
41    }
42
43    #[allow(dead_code)]
44    pub fn authenticate(&mut self, username: String, password: String) {
45        self.username = username;
46        self.password = password;
47        self.auth_enabled = true;
48        self.auth().expect("Authentication failed");
49    }
50
51    fn client(&self) -> Client {
52        match &self.client {
53            Some(c) => c.to_owned(),
54            None => Client::new(),
55        }
56    }
57
58    fn auth(&mut self) -> Result<String> {
59        let client = Client::new();
60        let resp = client
61            .post(&self.address)
62            .header("username", &self.username)
63            .header("password", &self.password)
64            .send()?
65            .text()?;
66
67        if resp == R_INVALID_CREDENTIALS {
68            panic!("Invalid credentials.");
69        }
70
71        self.token = resp.trim().to_string();
72
73        Ok(resp)
74    }
75
76    pub fn connect(&mut self) {
77        let r = self.http(Method::GET, &format!("ping"), "");
78
79        match r {
80            Err(e) => panic!("Unable to connect to the HyperDB server (E_001): {}", e),
81            Ok(r) => {
82                if r != R_PONG {
83                    panic!("Unable to connect to the HyperDB server (E_002).")
84                }
85
86                println!("Connected to {}", self.address);
87            }
88        }
89    }
90
91    pub fn ping(&self) -> Result<String> {
92        self.client()
93            .get(String::from(&self.address) + "/ping")
94            .send()?
95            .text()
96    }
97
98    pub fn http(&mut self, method: Method, url: &String, body: &str) -> Result<String> {
99        let m = method.clone();
100
101        let mut r = self
102            .client()
103            .request(method, format!("{}/{}", &self.address, url))
104            .header("Auth", &self.token)
105            .body(body.to_string())
106            .send()?
107            .text()?;
108
109        if r == R_AUTH_FAILED && self.auth_enabled {
110            self.auth()?;
111            r = self
112                .client()
113                .request(m, format!("{}/{}", &self.address, url))
114                .header("Auth", &self.token)
115                .body(body.to_string())
116                .send()?
117                .text()?;
118        }
119
120        Ok(r)
121    }
122
123    pub fn version(&mut self) -> Result<String> {
124        self.http(Method::GET, &format!(""), "")
125    }
126
127    pub fn has(&mut self, key: &str) -> Result<String> {
128        self.http(Method::GET, &format!("has/{}", key), "")
129    }
130
131    pub fn get(&mut self, key: &str) -> Result<String> {
132        self.http(Method::GET, &format!("data/{}", key), "")
133    }
134
135    pub fn set(&mut self, key: &str, value: &str) -> Result<String> {
136        self.http(Method::POST, &format!("data/{}", key), value)
137    }
138
139    pub fn delete(&mut self, key: &str) -> Result<String> {
140        self.http(Method::DELETE, &format!("data/{}", key), "")
141    }
142
143    pub fn all(&mut self) -> Result<String> {
144        self.http(Method::GET, &format!("data"), "")
145    }
146
147    pub fn clear(&mut self) -> Result<String> {
148        self.http(Method::DELETE, &format!("data"), "")
149    }
150
151    pub fn empty(&mut self) -> Result<String> {
152        self.http(Method::GET, &format!("empty"), "")
153    }
154
155    pub fn save(&mut self) -> Result<String> {
156        self.http(Method::POST, &format!("save"), "")
157    }
158
159    pub fn reload(&mut self) -> Result<String> {
160        self.http(Method::POST, &format!("reload"), "")
161    }
162
163    pub fn reset(&mut self) -> Result<String> {
164        self.http(Method::DELETE, &format!("reset"), "")
165    }
166}