use crate::{
errors::DetaError,
query::Query,
updater::Updater,
};
use serde_json::{Value, Map, json};
use serde::{Serialize, de::DeserializeOwned};
use ureq;
#[derive(Clone)]
pub struct Base {
pub name: String,
pub(crate) service: crate::Deta,
}
impl Base {
pub (crate) fn request(
&self,
method: &str,
path: &str,
body: Option<Value>
) -> Result<Value, DetaError> {
let url = format!("https://database.deta.sh/v1/{}/{}{}", self.service.project_id, self.name, path);
let req = ureq::request(method, &url)
.set("X-API-Key", &self.service.project_key);
let resp = match body {
Some(body) => req.send_json(body),
None => req.call()
};
if resp.is_err() {
return Err(DetaError::from(resp.err().unwrap()));
} else {
Ok(resp.unwrap().into_json().unwrap())
}
}
pub fn get(&self, key: &str) -> Result<Value, DetaError> {
self.request("GET", &format!("/items/{}", key), None)
}
pub fn get_as<T>(&self, key: &str) -> Result<T, DetaError> where T: DeserializeOwned {
let val = serde_json::from_value::<T>(self.get(key)?);
if val.is_err() {
return Err(DetaError::JSONError(val.err().unwrap()));
}
Ok(val?)
}
pub fn put<T>(&self, records: Vec<T>) -> Result<Value, DetaError> where T: Serialize {
if records.len() > 25 {
return Err(DetaError::PayloadError { msg: "maximum 25 records can be put at a time".to_string() });
}
let mut payload = Map::new();
let mut items = Vec::new();
for record in records {
items.push(serde_json::to_value(&record).unwrap());
}
payload.insert("items".to_string(), json!(items));
self.request("PUT", "/items", Some(json!(payload)))
}
pub fn insert<T>(&self, record: T) -> Result<Value, DetaError> where T: Serialize{
let mut data = Map::new();
data.insert("item".to_string(), serde_json::to_value(&record).unwrap());
self.request("POST", "/items", Some(json!(data)))
}
pub fn delete(&self, key: &str) -> Result<Value, DetaError> {
self.request("DELETE", &format!("/items/{}", key), None)
}
pub fn update(&self, key: &str) -> Updater {
Updater::new(self.clone(), key)
}
pub fn query(&self) -> Query {
Query::new(self.clone())
}
}