vrl/stdlib/
to_syslog_facility.rs

1use crate::compiler::prelude::*;
2
3fn to_syslog_facility(value: Value) -> Resolved {
4    let value = value.try_integer()?;
5    // Facility codes: https://en.wikipedia.org/wiki/Syslog#Facility
6    let code = match value {
7        0 => "kern",
8        1 => "user",
9        2 => "mail",
10        3 => "daemon",
11        4 => "auth",
12        5 => "syslog",
13        6 => "lpr",
14        7 => "news",
15        8 => "uucp",
16        9 => "cron",
17        10 => "authpriv",
18        11 => "ftp",
19        12 => "ntp",
20        13 => "security",
21        14 => "console",
22        15 => "solaris-cron",
23        16 => "local0",
24        17 => "local1",
25        18 => "local2",
26        19 => "local3",
27        20 => "local4",
28        21 => "local5",
29        22 => "local6",
30        23 => "local7",
31        _ => return Err(format!("facility code {value} not valid").into()),
32    };
33    Ok(code.into())
34}
35
36#[derive(Clone, Copy, Debug)]
37pub struct ToSyslogFacility;
38
39impl Function for ToSyslogFacility {
40    fn identifier(&self) -> &'static str {
41        "to_syslog_facility"
42    }
43
44    fn usage(&self) -> &'static str {
45        r#"Converts the `value`, a Syslog [facility code](https://en.wikipedia.org/wiki/Syslog#Facility), into its corresponding Syslog keyword. For example, `0` into `"kern"`, `1` into `"user"`, etc."#
46    }
47
48    fn category(&self) -> &'static str {
49        Category::Convert.as_ref()
50    }
51
52    fn internal_failure_reasons(&self) -> &'static [&'static str] {
53        &[
54            "`value` is not a valid Syslog [facility code](https://en.wikipedia.org/wiki/Syslog#Facility).",
55        ]
56    }
57
58    fn return_kind(&self) -> u16 {
59        kind::BYTES
60    }
61
62    fn parameters(&self) -> &'static [Parameter] {
63        const PARAMETERS: &[Parameter] = &[Parameter::required(
64            "value",
65            kind::INTEGER,
66            "The facility code.",
67        )];
68        PARAMETERS
69    }
70
71    fn examples(&self) -> &'static [Example] {
72        &[
73            example! {
74                title: "Coerce to a Syslog facility",
75                source: "to_syslog_facility!(4)",
76                result: Ok("auth"),
77            },
78            example! {
79                title: "invalid",
80                source: "to_syslog_facility!(500)",
81                result: Err(
82                    r#"function call error for "to_syslog_facility" at (0:24): facility code 500 not valid"#,
83                ),
84            },
85        ]
86    }
87
88    fn compile(
89        &self,
90        _state: &state::TypeState,
91        _ctx: &mut FunctionCompileContext,
92        arguments: ArgumentList,
93    ) -> Compiled {
94        let value = arguments.required("value");
95
96        Ok(ToSyslogFacilityFn { value }.as_expr())
97    }
98}
99
100#[derive(Debug, Clone)]
101struct ToSyslogFacilityFn {
102    value: Box<dyn Expression>,
103}
104
105impl FunctionExpression for ToSyslogFacilityFn {
106    fn resolve(&self, ctx: &mut Context) -> Resolved {
107        let value = self.value.resolve(ctx)?;
108
109        to_syslog_facility(value)
110    }
111
112    fn type_def(&self, _: &state::TypeState) -> TypeDef {
113        TypeDef::bytes().fallible()
114    }
115}
116
117#[cfg(test)]
118mod tests {
119    use super::*;
120    use crate::value;
121
122    test_function![
123        to_syslog_facility => ToSyslogFacility;
124
125        kern {
126            args: func_args![value: value!(0)],
127            want: Ok(value!("kern")),
128            tdef: TypeDef::bytes().fallible(),
129        }
130
131        user {
132            args: func_args![value: value!(1)],
133            want: Ok(value!("user")),
134            tdef: TypeDef::bytes().fallible(),
135        }
136
137        mail {
138            args: func_args![value: value!(2)],
139            want: Ok(value!("mail")),
140            tdef: TypeDef::bytes().fallible(),
141        }
142
143        daemon {
144            args: func_args![value: value!(3)],
145            want: Ok(value!("daemon")),
146            tdef: TypeDef::bytes().fallible(),
147        }
148
149        auth {
150            args: func_args![value: value!(4)],
151            want: Ok(value!("auth")),
152            tdef: TypeDef::bytes().fallible(),
153        }
154
155        syslog {
156            args: func_args![value: value!(5)],
157            want: Ok(value!("syslog")),
158            tdef: TypeDef::bytes().fallible(),
159        }
160
161        lpr {
162            args: func_args![value: value!(6)],
163            want: Ok(value!("lpr")),
164            tdef: TypeDef::bytes().fallible(),
165        }
166
167        news {
168            args: func_args![value: value!(7)],
169            want: Ok(value!("news")),
170            tdef: TypeDef::bytes().fallible(),
171        }
172
173        uucp {
174            args: func_args![value: value!(8)],
175            want: Ok(value!("uucp")),
176            tdef: TypeDef::bytes().fallible(),
177        }
178
179        cron {
180            args: func_args![value: value!(9)],
181            want: Ok(value!("cron")),
182            tdef: TypeDef::bytes().fallible(),
183        }
184
185        authpriv {
186            args: func_args![value: value!(10)],
187            want: Ok(value!("authpriv")),
188            tdef: TypeDef::bytes().fallible(),
189        }
190
191        ftp {
192            args: func_args![value: value!(11)],
193            want: Ok(value!("ftp")),
194            tdef: TypeDef::bytes().fallible(),
195        }
196
197        ntp {
198            args: func_args![value: value!(12)],
199            want: Ok(value!("ntp")),
200            tdef: TypeDef::bytes().fallible(),
201        }
202
203        security {
204            args: func_args![value: value!(13)],
205            want: Ok(value!("security")),
206            tdef: TypeDef::bytes().fallible(),
207        }
208
209        console {
210            args: func_args![value: value!(14)],
211            want: Ok(value!("console")),
212            tdef: TypeDef::bytes().fallible(),
213        }
214
215        solaris_cron {
216            args: func_args![value: value!(15)],
217            want: Ok(value!("solaris-cron")),
218            tdef: TypeDef::bytes().fallible(),
219        }
220
221        local0 {
222            args: func_args![value: value!(16)],
223            want: Ok(value!("local0")),
224            tdef: TypeDef::bytes().fallible(),
225        }
226
227        local1 {
228            args: func_args![value: value!(17)],
229            want: Ok(value!("local1")),
230            tdef: TypeDef::bytes().fallible(),
231        }
232
233        local2 {
234            args: func_args![value: value!(18)],
235            want: Ok(value!("local2")),
236            tdef: TypeDef::bytes().fallible(),
237        }
238
239        local3 {
240            args: func_args![value: value!(19)],
241            want: Ok(value!("local3")),
242            tdef: TypeDef::bytes().fallible(),
243        }
244
245        local4 {
246            args: func_args![value: value!(20)],
247            want: Ok(value!("local4")),
248            tdef: TypeDef::bytes().fallible(),
249        }
250
251        local5 {
252            args: func_args![value: value!(21)],
253            want: Ok(value!("local5")),
254            tdef: TypeDef::bytes().fallible(),
255        }
256
257        local6 {
258            args: func_args![value: value!(22)],
259            want: Ok(value!("local6")),
260            tdef: TypeDef::bytes().fallible(),
261        }
262
263        local7 {
264            args: func_args![value: value!(23)],
265            want: Ok(value!("local7")),
266            tdef: TypeDef::bytes().fallible(),
267        }
268
269        invalid_facility_larger_int {
270            args: func_args![value: value!(475)],
271            want: Err("facility code 475 not valid"),
272            tdef: TypeDef::bytes().fallible(),
273        }
274
275        invalid_facility_negative_int {
276            args: func_args![value: value!(-1)],
277            want: Err("facility code -1 not valid"),
278            tdef: TypeDef::bytes().fallible(),
279        }
280
281        invalid_facility_non_int {
282            args: func_args![value: value!("nope")],
283            want: Err("expected integer, got string"),
284            tdef: TypeDef::bytes().fallible(),
285        }
286    ];
287}