diff --git a/Cargo.toml b/Cargo.toml index a6e8e81..f807850 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ repository = "https://github.com/vulogov/rust_dynamic" bincode2 = "2.0.*" chrono = "0.4.*" dtoa = "1.0.*" +easy-error = "1.0.0" itoa = "1.0.*" nanoid = "0.4.*" num = "0.4.*" diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..1a92814 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +SOURCES=$(wildcard src/*.rs) + + +all: $(SOURCES) Makefile + cargo build + +rebuild: + make clean + make all + +test: + cargo test + +clean: + cargo clean + cargo update + +all: diff --git a/README.md b/README.md index cb3a9b6..6056a1f 100644 --- a/README.md +++ b/README.md @@ -196,6 +196,7 @@ While rust_dynamic crate is not strive to provide a full-featured functional int | Value.fmap() | Execute function to each element of the LIST or to the value and return new Value | | Value.map_float() | Execute function to each FLOAT element of the LIST or to the value and return new Value | | Value.push() | Ether add a new value to the list, or return a new Value | +| Value.push_inplace() | Push new Value to supported Value (LIST, QUEUE, FIFO, RESULT, METRIC) or return Error | | Value.maybe() | Takes a function which is if returns true, Value.maybe() returns value, if false Value::none() | | Value::left_right() | Takes a function which is if returns true, and a references on two Values. Value::left_right() returns clone of first value, if function return true, second othewise | | Value::freduce() | Takes two parameters - function which takes two values and returning a single value and initial value, reducing dynamic value to a single value by applying function to all elements | diff --git a/src/lib.rs b/src/lib.rs index 6b24695..0bb51e4 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,6 +27,7 @@ pub mod export; pub mod types; pub mod error; pub mod push; +pub mod push_inplace; pub mod pull; pub mod pop; pub mod hash; diff --git a/src/push_inplace.rs b/src/push_inplace.rs new file mode 100644 index 0000000..8285716 --- /dev/null +++ b/src/push_inplace.rs @@ -0,0 +1,62 @@ +use crate::value::{Value}; +use crate::metric::Metric; +use crate::types::*; +use easy_error::{Error, bail}; + +impl Value { + pub fn push_inplace(&mut self, value: Value) -> Result<&mut Value, Error> { + match self.dt { + LIST | RESULT => { + match &mut self.data { + Val::List(ref mut v) => { + let _ = v.push(value.clone()); + } + _ => { + bail!("Invalid List format for push() operation"); + } + } + return Ok(self); + } + QUEUE | FIFO => { + match &mut self.data { + Val::Queue(ref mut v) => { + let _ = v.push(value.clone()); + } + _ => { + bail!("Invalid Queue/Fifo format for push() operation"); + } + } + return Ok(self) + } + LAMBDA => { + match &mut self.data { + Val::Lambda(ref mut v) => { + let _ = v.push(value.clone()); + } + _ => { + bail!("Invalid Lambda format for push() operation"); + } + } + return Ok(self); + } + METRICS => { + if value.dt != FLOAT { + return Ok(self); + } + match &mut self.data { + Val::Metrics(ref mut v) => { + let _ = &v.push(Metric::new(value.cast_float().unwrap())); + let _ = &v.remove(0); + return Ok(self); + } + _ => { + bail!("Invalid Metric format for push() operation"); + } + } + } + _ => { + bail!("This Value do not support push() operation"); + } + } + } +} diff --git a/tests/push-test.rs b/tests/push-test.rs index f5f4cdf..29a6fd4 100644 --- a/tests/push-test.rs +++ b/tests/push-test.rs @@ -85,4 +85,11 @@ mod tests { let val = v.cast_list().unwrap(); assert_eq!(val[val.len()-1].cast_int().unwrap(), 42); } + + #[test] + fn test_push_list_push_inplace() { + let mut v = Value::list(); + v.push_inplace(Value::from_int(42)).unwrap(); + assert_eq!(v.len(), 1); + } }