use serde_json::{Map, Value};
use serde::{Serialize, Serializer};
use crate::{base::Base, errors::DetaError};
#[derive(Debug, PartialEq)]
pub enum Operation {
Set,
Delete,
Append,
Prepend,
Increment,
}
impl Operation {
pub fn as_string(&self) -> String {
format!("{:?}", self).to_lowercase()
}
}
pub struct Updater {
key: String,
base: Base,
map: Vec<(String, Value, Operation)>
}
impl Updater {
pub (crate) fn new(base: Base, key: &str) -> Updater {
Updater {
base,
key: key.to_string(),
map: Vec::new()
}
}
pub fn operation(mut self, op: Operation, field: &str, value: Value) -> Self {
self.map.push((field.to_string(), value, op));
self
}
pub fn run(&self) -> Result<Value, DetaError> {
self.base.request("PATCH", &format!("/items/{}", self.key), Some(serde_json::to_value(self).unwrap()))
}
}
impl Serialize for Updater {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut map = Map::new();
for &(ref field, ref value, ref operation) in &self.map {
let operation_vec = map.entry(operation.as_string())
.or_insert(Value::Array(Vec::new())).as_array_mut().unwrap();
if operation == &Operation::Delete {
operation_vec.push(Value::String(field.clone()));
} else {
let mut inner_map = Map::new();
inner_map.insert(field.clone(), value.clone());
operation_vec.push(Value::Object(inner_map));
}
}
Value::Object(map).serialize(serializer)
}
}