vrl/stdlib/
values.rs

1use crate::compiler::prelude::*;
2
3fn values(value: Value) -> Resolved {
4    let object = value.try_object()?;
5    let values = object.into_values();
6    Ok(Value::Array(values.collect()))
7}
8
9#[derive(Debug)]
10pub struct Values;
11
12impl Function for Values {
13    fn identifier(&self) -> &'static str {
14        "values"
15    }
16
17    fn usage(&self) -> &'static str {
18        "Returns the values from the object passed into the function."
19    }
20
21    fn category(&self) -> &'static str {
22        Category::Enumerate.as_ref()
23    }
24
25    fn return_kind(&self) -> u16 {
26        kind::ARRAY
27    }
28
29    fn return_rules(&self) -> &'static [&'static str] {
30        &["Returns an array of all the values."]
31    }
32
33    fn parameters(&self) -> &'static [Parameter] {
34        const PARAMETERS: &[Parameter] = &[Parameter::required(
35            "value",
36            kind::OBJECT,
37            "The object to extract values from.",
38        )];
39        PARAMETERS
40    }
41
42    fn examples(&self) -> &'static [Example] {
43        &[
44            example! {
45                title: "Get values from the object",
46                source: r#"values({"key1": "val1", "key2": "val2"})"#,
47                result: Ok(r#"["val1", "val2"]"#),
48            },
49            example! {
50                title: "Get values from a complex object",
51                source: r#"values({"key1": "val1", "key2": [1, 2, 3], "key3": {"foo": "bar"}})"#,
52                result: Ok(r#"["val1", [1, 2, 3], {"foo": "bar"}]"#),
53            },
54        ]
55    }
56
57    fn compile(
58        &self,
59        _state: &TypeState,
60        _ctx: &mut FunctionCompileContext,
61        arguments: ArgumentList,
62    ) -> Compiled {
63        let value = arguments.required("value");
64        Ok(ValuesFn { value }.as_expr())
65    }
66}
67
68#[derive(Debug, Clone)]
69struct ValuesFn {
70    value: Box<dyn Expression>,
71}
72
73impl FunctionExpression for ValuesFn {
74    fn resolve(&self, ctx: &mut Context) -> Resolved {
75        values(self.value.resolve(ctx)?)
76    }
77
78    fn type_def(&self, state: &state::TypeState) -> TypeDef {
79        // The type of all possible values is merged together to get a more specific value than just `TypeDef::any()`
80        let merged_kind = self
81            .value
82            .type_def(state)
83            .kind()
84            .as_object()
85            .unwrap()
86            .reduced_kind();
87        TypeDef::array(Collection::empty().with_unknown(merged_kind)).infallible()
88    }
89}