Skip to content

Commit 4c9da9b

Browse files
committed
Merge with main
2 parents a64fe7e + bab1cd5 commit 4c9da9b

File tree

11 files changed

+1065
-559
lines changed

11 files changed

+1065
-559
lines changed

Cargo.lock

Lines changed: 542 additions & 550 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ string_path = []
3838
datadog = ["datadog_filter", "datadog_grok", "datadog_search"]
3939
datadog_filter = ["datadog_search", "dep:regex", "dep:dyn-clone"]
4040
datadog_grok = ["value", "parsing", "dep:nom", "dep:peeking_take_while", "dep:serde_json", "dep:onig", "dep:lalrpop-util", "dep:thiserror", "dep:chrono", "dep:chrono-tz", "dep:percent-encoding"]
41-
datadog_search = ["dep:pest", "dep:pest_derive", "dep:itertools", "dep:once_cell", "dep:regex"]
41+
datadog_search = ["dep:pest", "dep:pest_derive", "dep:itertools", "dep:once_cell", "dep:regex", "dep:serde"]
4242

4343
# Features that aren't used as often (default off)
4444
cli = ["stdlib", "dep:serde_json", "dep:thiserror", "dep:clap", "dep:exitcode", "dep:webbrowser", "dep:rustyline", "dep:prettytable-rs"]
@@ -142,11 +142,11 @@ hex = { version = "0.4", optional = true }
142142
hmac = { version = "0.12", optional = true }
143143
iana-time-zone = { version = "0.1", optional = true }
144144
idna = { version = "0.5", optional = true }
145-
indexmap = { version = "~2.4.0", default-features = false, features = ["std"], optional = true}
145+
indexmap = { version = "2", default-features = false, features = ["std"], optional = true}
146146
influxdb-line-protocol = { version = "2.0.0", optional = true }
147147
indoc = {version = "2", optional = true }
148-
itertools = { version = "0.13", default-features = false, optional = true }
149-
lalrpop-util = { version = "0.20", optional = true }
148+
itertools = { version = "0.13", default-features = false, features=["use_std"], optional = true }
149+
lalrpop-util = { version = "0.21", optional = true }
150150
linux-audit-parser = { version = "0.1.1", default-features = false, optional = true }
151151
mlua = { version = "0.9", default-features = false, features = ["lua54", "send", "vendored"], optional = true}
152152
nom = { version = "7", default-features = false, features = ["std"], optional = true }

benches/stdlib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ criterion_group!(
160160
to_syslog_severity,
161161
to_unix_timestamp,
162162
truncate,
163+
unflatten,
163164
unique,
164165
// TODO: Cannot pass a Path to bench_function
165166
//unnest
@@ -2789,6 +2790,31 @@ bench_function! {
27892790
}
27902791
}
27912792

2793+
bench_function! {
2794+
unflatten => vrl::stdlib::Unflatten;
2795+
2796+
nested_map {
2797+
args: func_args![value: value!({"parent.child1": 1, "parent.child2": 2, key: "val"})],
2798+
want: Ok(value!({parent: {child1: 1, child2: 2}, key: "val"})),
2799+
}
2800+
2801+
map_and_array {
2802+
args: func_args![value: value!({
2803+
"parent.child1": [1, [2, 3]],
2804+
"parent.child2.grandchild1": 1,
2805+
"parent.child2.grandchild2": [1, [2, 3], 4],
2806+
"key": "val",
2807+
})],
2808+
want: Ok(value!({
2809+
"parent": {
2810+
"child1": [1, [2, 3]],
2811+
"child2": {"grandchild1": 1, "grandchild2": [1, [2, 3], 4]},
2812+
},
2813+
"key": "val",
2814+
})),
2815+
}
2816+
}
2817+
27922818
bench_function! {
27932819
unique => vrl::stdlib::Unique;
27942820

changelog.d/81.feature.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Added `unflatten` function to inverse the result of the `flatten` function. This function is useful when you want to convert a flattened object back to its original form.
2+
3+
authors: jorgehermo9
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# object: { "a.b.c.d": 1, "a.b.c.e": 2, "a.b.f": 3, "a.g": 4 }
2+
# result: { "a.b.c.d": 1, "a.b.c.e": 2, "a.b.f": 3, "a.g": 4 }
3+
4+
flatten(unflatten(.))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# object: { "a": { "b": { "c": { "d": 1, "e": 2 }, "f": 3 }, "g": 4 } }
2+
# result: { "a.b.c.d": 1, "a.b.c.e": 2, "a.b.f": 3, "a.g": 4 }
3+
4+
flatten(.)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# object: { "a": { "b": { "c": { "d": 1, "e": 2 }, "f": 3 }, "g": 4 } }
2+
# result: { "a": { "b": { "c": { "d": 1, "e": 2 }, "f": 3 }, "g": 4 } }
3+
4+
unflatten(flatten(.))
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# object: { "a.b.c.d": 1, "a.b.c.e": 2, "a.b.f": 3, "a.g": 4 }
2+
# result: { "a": { "b": { "c": { "d": 1, "e": 2 }, "f": 3 }, "g": 4 } }
3+
4+
unflatten(.)

src/datadog/search/node.rs

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
use once_cell::sync::Lazy;
22
use regex::Regex;
3+
use serde::{Deserialize, Deserializer, Serialize, Serializer};
34

45
use super::grammar::{unescape, DEFAULT_FIELD};
56

67
/// This enum represents value comparisons that Queries might perform
7-
#[derive(Debug, Copy, Clone)]
8+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
89
pub enum Comparison {
910
/// Greater than.
1011
Gt,
@@ -31,7 +32,7 @@ impl Comparison {
3132
/// This enum represents the values we might be using in a comparison, whether
3233
/// they are Strings, Numbers (currently only floating point numbers) or an
3334
/// Unbounded comparison with no terminating value.
34-
#[derive(Debug, Clone)]
35+
#[derive(Clone, Debug, PartialEq)]
3536
pub enum ComparisonValue {
3637
Unbounded,
3738
String(String),
@@ -80,14 +81,14 @@ impl<T: AsRef<str>> From<T> for ComparisonValue {
8081

8182
/// This enum represents the tokens in a range, including "greater than (or equal to)"
8283
/// for the left bracket, "less than (or equal to) in the right bracket, and range values.
83-
#[derive(Debug, Clone)]
84+
#[derive(Clone, Debug, PartialEq)]
8485
pub enum Range {
8586
Comparison(Comparison),
8687
Value(ComparisonValue),
8788
}
8889

8990
/// This enum represents the AND or OR Boolean operations we might perform on QueryNodes.
90-
#[derive(Debug, Copy, Clone)]
91+
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
9192
pub enum BooleanType {
9293
And,
9394
Or,
@@ -133,7 +134,7 @@ impl BooleanBuilder {
133134
}
134135

135136
/// QueryNodes represent specific search criteria to be enforced.
136-
#[derive(Debug, Clone)]
137+
#[derive(Clone, Debug, PartialEq)]
137138
pub enum QueryNode {
138139
/// Match all documents.
139140
MatchAllDocs,
@@ -344,6 +345,29 @@ impl QueryNode {
344345
}
345346
}
346347

348+
impl<'de> Deserialize<'de> for QueryNode {
349+
fn deserialize<D>(deserializer: D) -> Result<QueryNode, D::Error>
350+
where
351+
D: Deserializer<'de>,
352+
{
353+
use serde::de::Error;
354+
355+
let s = String::deserialize(deserializer)?;
356+
357+
s.parse::<QueryNode>()
358+
.map_err(|e| D::Error::custom(e.to_string()))
359+
}
360+
}
361+
362+
impl Serialize for QueryNode {
363+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
364+
where
365+
S: Serializer,
366+
{
367+
serializer.serialize_str(self.to_lucene().as_str())
368+
}
369+
}
370+
347371
/// Enum representing Lucene's concept of whether a node should occur.
348372
#[derive(Debug)]
349373
pub enum LuceneOccur {
@@ -364,3 +388,29 @@ static ESCAPE_RE: Lazy<Regex> = Lazy::new(|| Regex::new("^\"(.+)\"$").unwrap());
364388
fn escape_quotes<T: AsRef<str>>(value: T) -> String {
365389
ESCAPE_RE.replace_all(value.as_ref(), "$1").to_string()
366390
}
391+
392+
#[cfg(test)]
393+
mod tests {
394+
use super::*;
395+
396+
#[test]
397+
fn query_node_serializes_to_string() {
398+
assert_eq!(
399+
serde_json::to_string(&QueryNode::AttributeExists {
400+
attr: "something".into()
401+
})
402+
.unwrap(),
403+
r#""_exists_:something""#
404+
);
405+
}
406+
407+
#[test]
408+
fn query_node_deserializes_from_string() {
409+
assert_eq!(
410+
serde_json::from_str::<QueryNode>(r#""_missing_:something_else""#).unwrap(),
411+
QueryNode::AttributeMissing {
412+
attr: "something_else".into()
413+
}
414+
);
415+
}
416+
}

src/stdlib/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,7 @@ cfg_if::cfg_if! {
204204
mod to_unix_timestamp;
205205
mod community_id;
206206
mod truncate;
207+
mod unflatten;
207208
mod type_def;
208209
mod unique;
209210
mod unnest;
@@ -383,6 +384,7 @@ cfg_if::cfg_if! {
383384
pub use to_unix_timestamp::ToUnixTimestamp;
384385
pub use truncate::Truncate;
385386
pub use type_def::TypeDef;
387+
pub use unflatten::Unflatten;
386388
pub use unique::Unique;
387389
pub use unnest::Unnest;
388390
pub use upcase::Upcase;
@@ -572,6 +574,7 @@ pub fn all() -> Vec<Box<dyn Function>> {
572574
Box::new(CommunityID),
573575
Box::new(Truncate),
574576
Box::new(TypeDef),
577+
Box::new(Unflatten),
575578
Box::new(Unique),
576579
Box::new(Unnest),
577580
Box::new(Upcase),

0 commit comments

Comments
 (0)