reddb_client/connector/
http.rs1use std::fmt;
13
14#[derive(Debug, Clone)]
15pub enum Auth {
16 Anonymous,
17 Bearer(String),
18}
19
20#[derive(Debug)]
21pub enum HttpError {
22 Network(String),
23 Http { status: u16, body: String },
24 Decode(String),
25}
26
27impl fmt::Display for HttpError {
28 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
29 match self {
30 Self::Network(m) => write!(f, "network: {m}"),
31 Self::Http { status, body } => write!(f, "HTTP {status}: {body}"),
32 Self::Decode(m) => write!(f, "decode: {m}"),
33 }
34 }
35}
36
37impl std::error::Error for HttpError {}
38
39type Result<T> = std::result::Result<T, HttpError>;
40
41pub fn query_one_shot(base_url: &str, sql: &str, auth: &Auth) -> Result<String> {
48 let url = format!("{}/query", base_url.trim_end_matches('/'));
49 let body = serde_json::json!({ "query": sql }).to_string();
50 let mut req = ureq::post(&url).header("content-type", "application/json");
51 if let Auth::Bearer(token) = auth {
52 req = req.header("authorization", &format!("Bearer {token}"));
53 }
54 let mut resp = req
55 .send(body.as_bytes())
56 .map_err(|e| HttpError::Network(e.to_string()))?;
57 let status = resp.status().as_u16();
58 let body_text = resp
59 .body_mut()
60 .read_to_string()
61 .map_err(|e| HttpError::Decode(e.to_string()))?;
62 if status >= 400 {
63 return Err(HttpError::Http {
64 status,
65 body: body_text,
66 });
67 }
68 Ok(body_text)
69}