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 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}