reddb_client/connector/
http.rs1use std::fmt;
13
14use reddb_wire::auth::{
15 apikey_authorization_value, bearer_authorization_value, AUTHORIZATION_HEADER,
16};
17
18#[derive(Clone)]
19pub enum Auth {
20 Anonymous,
21 Bearer(String),
22 Basic { user: String, pass: String },
23 ApiKey(String),
24}
25
26impl fmt::Debug for Auth {
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 match self {
29 Self::Anonymous => f.write_str("Anonymous"),
30 Self::Bearer(_) => f.debug_tuple("Bearer").field(&"<redacted>").finish(),
31 Self::Basic { .. } => f
32 .debug_struct("Basic")
33 .field("user", &"<redacted>")
34 .field("pass", &"<redacted>")
35 .finish(),
36 Self::ApiKey(_) => f.debug_tuple("ApiKey").field(&"<redacted>").finish(),
37 }
38 }
39}
40
41#[derive(Debug)]
42pub enum HttpError {
43 Network(String),
44 Http { status: u16, body: String },
45 Decode(String),
46}
47
48impl fmt::Display for HttpError {
49 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50 match self {
51 Self::Network(m) => write!(f, "network: {m}"),
52 Self::Http { status, body } => write!(f, "HTTP {status}: {body}"),
53 Self::Decode(m) => write!(f, "decode: {m}"),
54 }
55 }
56}
57
58impl std::error::Error for HttpError {}
59
60type Result<T> = std::result::Result<T, HttpError>;
61
62pub fn query_one_shot(base_url: &str, sql: &str, auth: &Auth) -> Result<String> {
69 let url = format!("{}/query", base_url.trim_end_matches('/'));
70 let body = serde_json::json!({ "query": sql }).to_string();
71 let mut req = ureq::post(&url).header("content-type", "application/json");
72 match auth {
73 Auth::Anonymous => {}
74 Auth::Bearer(token) => {
75 req = req.header(AUTHORIZATION_HEADER, &bearer_authorization_value(token));
76 }
77 Auth::ApiKey(key) => {
78 req = req.header(AUTHORIZATION_HEADER, &apikey_authorization_value(key));
79 }
80 Auth::Basic { .. } => {}
81 }
82 let mut resp = req
83 .send(body.as_bytes())
84 .map_err(|e| HttpError::Network(e.to_string()))?;
85 let status = resp.status().as_u16();
86 let body_text = resp
87 .body_mut()
88 .read_to_string()
89 .map_err(|e| HttpError::Decode(e.to_string()))?;
90 if status >= 400 {
91 return Err(HttpError::Http {
92 status,
93 body: body_text,
94 });
95 }
96 Ok(body_text)
97}