vrl/stdlib/
downcase.rs

1use crate::compiler::prelude::*;
2
3fn downcase(value: &Value) -> Resolved {
4    Ok(value.try_bytes_utf8_lossy()?.to_lowercase().into())
5}
6
7#[derive(Clone, Copy, Debug)]
8pub struct Downcase;
9
10impl Function for Downcase {
11    fn identifier(&self) -> &'static str {
12        "downcase"
13    }
14
15    fn usage(&self) -> &'static str {
16        "Downcases the `value` string, where downcase is defined according to the Unicode Derived Core Property Lowercase."
17    }
18
19    fn category(&self) -> &'static str {
20        Category::String.as_ref()
21    }
22
23    fn return_kind(&self) -> u16 {
24        kind::BYTES
25    }
26
27    fn parameters(&self) -> &'static [Parameter] {
28        const PARAMETERS: &[Parameter] = &[Parameter::required(
29            "value",
30            kind::BYTES,
31            "The string to convert to lowercase.",
32        )];
33        PARAMETERS
34    }
35
36    fn compile(
37        &self,
38        _state: &state::TypeState,
39        _ctx: &mut FunctionCompileContext,
40        arguments: ArgumentList,
41    ) -> Compiled {
42        let value = arguments.required("value");
43
44        Ok(DowncaseFn { value }.as_expr())
45    }
46
47    fn examples(&self) -> &'static [Example] {
48        &[
49            example! {
50                title: "Downcase a string",
51                source: r#"downcase("Hello, World!")"#,
52                result: Ok("hello, world!"),
53            },
54            example! {
55                title: "Downcase with number",
56                source: r#"downcase("FOO 2 BAR")"#,
57                result: Ok("foo 2 bar"),
58            },
59        ]
60    }
61}
62
63#[derive(Debug, Clone)]
64struct DowncaseFn {
65    value: Box<dyn Expression>,
66}
67
68impl FunctionExpression for DowncaseFn {
69    fn resolve(&self, ctx: &mut Context) -> Resolved {
70        let value = self.value.resolve(ctx)?;
71        downcase(&value)
72    }
73
74    fn type_def(&self, _: &state::TypeState) -> TypeDef {
75        TypeDef::bytes().infallible()
76    }
77}
78
79#[cfg(test)]
80mod tests {
81    use super::*;
82    use crate::value;
83
84    test_function![
85        downcase => Downcase;
86
87        simple {
88            args: func_args![value: "FOO 2 bar"],
89            want: Ok(value!("foo 2 bar")),
90            tdef: TypeDef::bytes(),
91        }
92    ];
93}