diff --git a/src/kvstore.rs b/src/kvstore.rs index 094a46d..ea4a296 100644 --- a/src/kvstore.rs +++ b/src/kvstore.rs @@ -9,38 +9,39 @@ pub struct KvElement { pub updated_at: DateTime, pub expire_at: DateTime, pub update_count: i32, - pub locked: bool + pub locked: bool, } pub struct KvStore { - container: CHashMap + container: CHashMap, } -impl KvStore -{ - pub fn new() -> KvStore - { +impl KvStore { + pub fn new() -> KvStore { // TODO: prepare looped persistence KvStore { - container: CHashMap::new() + container: CHashMap::new(), } } pub fn set(&self, key: String, value: Vec) -> Option { // TODO: prepare iterative persistence - let mime_type = tree_magic::from_u8(value.as_ref()); match &mut self.container.get_mut(&key) { Some(kv_element) => { - kv_element.data = value; - kv_element.mime_type = mime_type; + if !kv_element.locked { + let mime_type = tree_magic::from_u8(value.as_ref()); + kv_element.data = value; + kv_element.mime_type = mime_type; + } kv_element.updated_at = Utc::now(); - kv_element.update_count = kv_element.update_count + 1; + kv_element.update_count = kv_element.update_count + 1; Some(kv_element.to_owned()) - }, + } None => { + let mime_type = tree_magic::from_u8(value.as_ref()); let kv_element = KvElement { data: value, - mime_type: mime_type, + mime_type, created_at: Utc::now(), updated_at: Utc::now(), expire_at: Utc::now(), @@ -55,7 +56,7 @@ impl KvStore pub fn get(&self, key: String) -> Option { match self.container.get(&key) { Some(value) => Some(value.clone()), - None => None + None => None, } } @@ -64,8 +65,26 @@ impl KvStore Some(kv_element) => { kv_element.locked = to_lock; true - }, - None => false + } + None => false, + } + } + + pub fn increment_or_decrement(&self, key: String, value: f64) -> bool { + match &mut self.container.get_mut(&key) { + Some(kv_element) => { + let byte_to_string = String::from_utf8(kv_element.clone().data).unwrap(); // TODO: handle convert to string error + match byte_to_string.trim().parse::() { + Ok(initial_value) => { + kv_element.data = (initial_value + value).to_string().into_bytes(); + kv_element.updated_at = Utc::now(); + kv_element.update_count = kv_element.update_count + 1; + true + } + Err(_) => false, + } + } + None => false, } } @@ -74,4 +93,4 @@ impl KvStore pub fn drop(&self, key: String) { self.container.remove(&key); } -} \ No newline at end of file +} diff --git a/src/server.rs b/src/server.rs index a9bcea5..20c8561 100644 --- a/src/server.rs +++ b/src/server.rs @@ -119,8 +119,14 @@ impl Server { std::process::id() ); info!("Lucid API Endpoint: https://{}/api/", bind_endpoint); - info!("SSL Certificate: {}", &configuration.general.ssl_certificate); - info!("SSL Private Key: {}", &configuration.general.ssl_certificate_key); + info!( + "SSL Certificate: {}", + &configuration.general.ssl_certificate + ); + info!( + "SSL Private Key: {}", + &configuration.general.ssl_certificate_key + ); info!("Use Ctrl+C to stop the server."); instance .tls() @@ -219,11 +225,30 @@ async fn patch_key( patch_value: PatchValue, ) -> Result { if let Some(_) = store.get(key.clone()) { - match patch_value.operation.as_str() { - "lock" | "unlock" => { - let r = store.switch_lock(key.to_string(), true); - println!("{}", r); - Ok("") + match patch_value.operation.to_lowercase().as_str() { + "lock" => { + store.switch_lock(key.to_string(), true); + Ok(warp::reply::json(&JsonMessage { + message: "The specified key was successfully locked.".to_string(), + })) + } + "unlock" => { + store.switch_lock(key.to_string(), false); + Ok(warp::reply::json(&JsonMessage { + message: "The specified key was successfully unlocked.".to_string(), + })) + } + "increment" => { + store.increment_or_decrement(key.to_string(), 1.0); + Ok(warp::reply::json(&JsonMessage { + message: "The specified key was successfully incremented.".to_string(), + })) + } + "decrement" => { + store.increment_or_decrement(key.to_string(), -1.0); + Ok(warp::reply::json(&JsonMessage { + message: "The specified key was successfully decremented.".to_string(), + })) } _ => Err(reject::custom(Error::InvalidOperation { operation: patch_value.operation,