vrl/stdlib/
to_syslog_level.rs

1use crate::compiler::prelude::*;
2
3fn to_syslog_level(value: Value) -> Resolved {
4    let value = value.try_integer()?;
5    // Severity levels: https://en.wikipedia.org/wiki/Syslog#Severity_level
6    let level = match value {
7        0 => "emerg",
8        1 => "alert",
9        2 => "crit",
10        3 => "err",
11        4 => "warning",
12        5 => "notice",
13        6 => "info",
14        7 => "debug",
15        _ => return Err(format!("severity level {value} not valid").into()),
16    };
17    Ok(level.into())
18}
19
20#[derive(Clone, Copy, Debug)]
21pub struct ToSyslogLevel;
22
23impl Function for ToSyslogLevel {
24    fn identifier(&self) -> &'static str {
25        "to_syslog_level"
26    }
27
28    fn usage(&self) -> &'static str {
29        r#"Converts the `value`, a Syslog [severity level](https://en.wikipedia.org/wiki/Syslog#Severity_level), into its corresponding keyword, i.e. 0 into `"emerg"`, 1 into `"alert"`, etc."#
30    }
31
32    fn category(&self) -> &'static str {
33        Category::Convert.as_ref()
34    }
35
36    fn internal_failure_reasons(&self) -> &'static [&'static str] {
37        &[
38            "`value` isn't a valid Syslog [severity level](https://en.wikipedia.org/wiki/Syslog#Severity_level).",
39        ]
40    }
41
42    fn return_kind(&self) -> u16 {
43        kind::BYTES
44    }
45
46    fn parameters(&self) -> &'static [Parameter] {
47        const PARAMETERS: &[Parameter] = &[Parameter::required(
48            "value",
49            kind::INTEGER,
50            "The severity level.",
51        )];
52        PARAMETERS
53    }
54
55    fn examples(&self) -> &'static [Example] {
56        &[
57            example! {
58                title: "Coerce to a Syslog level",
59                source: "to_syslog_level!(5)",
60                result: Ok("notice"),
61            },
62            example! {
63                title: "invalid",
64                source: "to_syslog_level!(500)",
65                result: Err(
66                    r#"function call error for "to_syslog_level" at (0:21): severity level 500 not valid"#,
67                ),
68            },
69        ]
70    }
71
72    fn compile(
73        &self,
74        _state: &state::TypeState,
75        _ctx: &mut FunctionCompileContext,
76        arguments: ArgumentList,
77    ) -> Compiled {
78        let value = arguments.required("value");
79
80        Ok(ToSyslogLevelFn { value }.as_expr())
81    }
82}
83
84#[derive(Debug, Clone)]
85struct ToSyslogLevelFn {
86    value: Box<dyn Expression>,
87}
88
89impl FunctionExpression for ToSyslogLevelFn {
90    fn resolve(&self, ctx: &mut Context) -> Resolved {
91        let value = self.value.resolve(ctx)?;
92
93        to_syslog_level(value)
94    }
95
96    fn type_def(&self, _: &state::TypeState) -> TypeDef {
97        TypeDef::bytes().fallible()
98    }
99}
100
101#[cfg(test)]
102mod tests {
103    use super::*;
104    use crate::value;
105
106    test_function![
107        to_syslog_level => ToSyslogLevel;
108
109        emergency {
110            args: func_args![value: value!(0)],
111            want: Ok(value!("emerg")),
112            tdef: TypeDef::bytes().fallible(),
113        }
114
115        alert {
116            args: func_args![value: value!(1)],
117            want: Ok(value!("alert")),
118            tdef: TypeDef::bytes().fallible(),
119        }
120
121        critical {
122            args: func_args![value: value!(2)],
123            want: Ok(value!("crit")),
124            tdef: TypeDef::bytes().fallible(),
125        }
126
127        error {
128            args: func_args![value: value!(3)],
129            want: Ok(value!("err")),
130            tdef: TypeDef::bytes().fallible(),
131        }
132
133        warning {
134            args: func_args![value: value!(4)],
135            want: Ok(value!("warning")),
136            tdef: TypeDef::bytes().fallible(),
137        }
138
139        notice {
140            args: func_args![value: value!(5)],
141            want: Ok(value!("notice")),
142            tdef: TypeDef::bytes().fallible(),
143        }
144
145        informational {
146            args: func_args![value: value!(6)],
147            want: Ok(value!("info")),
148            tdef: TypeDef::bytes().fallible(),
149        }
150
151        debug {
152            args: func_args![value: value!(7)],
153            want: Ok(value!("debug")),
154            tdef: TypeDef::bytes().fallible(),
155        }
156
157        invalid_severity_next_int {
158            args: func_args![value: value!(8)],
159            want: Err("severity level 8 not valid"),
160            tdef: TypeDef::bytes().fallible(),
161        }
162
163        invalid_severity_larger_int {
164            args: func_args![value: value!(475)],
165            want: Err("severity level 475 not valid"),
166            tdef: TypeDef::bytes().fallible(),
167        }
168
169        invalid_severity_negative_int {
170            args: func_args![value: value!(-1)],
171            want: Err("severity level -1 not valid"),
172            tdef: TypeDef::bytes().fallible(),
173        }
174    ];
175}