diff --git a/lib/src/sql/ident.rs b/lib/src/sql/ident.rs index 91af8bde..6bf6a9d6 100644 --- a/lib/src/sql/ident.rs +++ b/lib/src/sql/ident.rs @@ -31,6 +31,14 @@ impl<'a> From<&'a str> for Ident { } } +impl<'a> From<&'a String> for Ident { + fn from(i: &String) -> Ident { + Ident { + name: String::from(i), + } + } +} + impl fmt::Display for Ident { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "{}", escape(&self.name, &val_char, "`")) diff --git a/lib/src/sql/part.rs b/lib/src/sql/part.rs index aa10ccec..61cc0265 100644 --- a/lib/src/sql/part.rs +++ b/lib/src/sql/part.rs @@ -71,11 +71,17 @@ impl From for Part { } } +impl From<&String> for Part { + fn from(v: &String) -> Self { + Part::Field(Ident::from(v)) + } +} + impl From<&str> for Part { fn from(v: &str) -> Self { match v.parse::() { Ok(v) => Part::from(v), - _ => Part::from(v.to_string()), + _ => Part::from(v.to_owned()), } } } diff --git a/lib/src/sql/value/every.rs b/lib/src/sql/value/every.rs new file mode 100644 index 00000000..e86c9cd8 --- /dev/null +++ b/lib/src/sql/value/every.rs @@ -0,0 +1,50 @@ +use crate::sql::idiom::Idiom; +use crate::sql::part::Part; +use crate::sql::value::Value; + +impl Value { + pub fn every(&self) -> Vec { + self._every(Idiom::default()) + } + fn _every(&self, prev: Idiom) -> Vec { + match self { + // Current path part is an object + Value::Object(v) => v + .value + .iter() + .flat_map(|(k, v)| v._every(prev.add(Part::from(k)))) + .collect::>(), + // Current path part is an array + Value::Array(v) => v + .value + .iter() + .enumerate() + .flat_map(|(i, v)| v._every(prev.add(Part::from(i)))) + .collect::>(), + // Process everything else + _ => vec![prev], + } + } +} + +#[cfg(test)] +mod tests { + + use super::*; + use crate::sql::idiom::Idiom; + use crate::sql::test::Parse; + + #[test] + fn every() { + let val = Value::parse("{ test: { something: [{ age: 34, tags: ['code', 'databases'] }, { age: 36, tags: ['design', 'operations'] }] } }"); + let res = vec![ + Idiom::parse("test.something[0].age"), + Idiom::parse("test.something[0].tags[0]"), + Idiom::parse("test.something[0].tags[1]"), + Idiom::parse("test.something[1].age"), + Idiom::parse("test.something[1].tags[0]"), + Idiom::parse("test.something[1].tags[1]"), + ]; + assert_eq!(res, val.every()); + } +} diff --git a/lib/src/sql/value/mod.rs b/lib/src/sql/value/mod.rs index 6c422430..13726c16 100644 --- a/lib/src/sql/value/mod.rs +++ b/lib/src/sql/value/mod.rs @@ -9,6 +9,7 @@ mod def; mod del; mod diff; mod each; +mod every; mod first; mod get; mod increment;