vrl/stdlib/
encode_snappy.rs

1use crate::compiler::prelude::*;
2use snap::raw::Encoder;
3
4fn encode_snappy(value: Value) -> Resolved {
5    let value = value.try_bytes()?;
6    let mut encoder = Encoder::new();
7    let result = encoder.compress_vec(&value);
8
9    match result {
10        Ok(buf) => Ok(Value::Bytes(buf.into())),
11        Err(_) => Err("unable to encode value with Snappy encoder".into()),
12    }
13}
14
15#[derive(Clone, Copy, Debug)]
16pub struct EncodeSnappy;
17
18impl Function for EncodeSnappy {
19    fn identifier(&self) -> &'static str {
20        "encode_snappy"
21    }
22
23    fn examples(&self) -> &'static [Example] {
24        &[Example {
25            title: "demo string",
26            source: r#"encode_base64(encode_snappy!("The quick brown fox jumps over 13 lazy dogs."))"#,
27            result: Ok("LKxUaGUgcXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgMTMgbGF6eSBkb2dzLg=="),
28        }]
29    }
30
31    fn compile(
32        &self,
33        _state: &state::TypeState,
34        _ctx: &mut FunctionCompileContext,
35        arguments: ArgumentList,
36    ) -> Compiled {
37        let value = arguments.required("value");
38
39        Ok(EncodeSnappyFn { value }.as_expr())
40    }
41
42    fn parameters(&self) -> &'static [Parameter] {
43        &[Parameter {
44            keyword: "value",
45            kind: kind::BYTES,
46            required: true,
47        }]
48    }
49}
50
51#[derive(Clone, Debug)]
52struct EncodeSnappyFn {
53    value: Box<dyn Expression>,
54}
55
56impl FunctionExpression for EncodeSnappyFn {
57    fn resolve(&self, ctx: &mut Context) -> Resolved {
58        let value = self.value.resolve(ctx)?;
59
60        encode_snappy(value)
61    }
62
63    fn type_def(&self, _state: &state::TypeState) -> TypeDef {
64        // Always fallible due to the possibility of decoding errors that VRL can't detect
65        TypeDef::bytes().fallible()
66    }
67}
68
69#[cfg(test)]
70mod test {
71    use super::*;
72    use crate::value;
73    use nom::AsBytes;
74
75    fn decode_base64(text: &str) -> Vec<u8> {
76        base64_simd::STANDARD
77            .decode_to_vec(text)
78            .expect("Cannot decode from Base64")
79    }
80
81    test_function![
82        encode_snappy => EncodeSnappy;
83
84        success {
85            args: func_args![value: value!("The quick brown fox jumps over 13 lazy dogs.")],
86            want: Ok(value!(decode_base64("LKxUaGUgcXVpY2sgYnJvd24gZm94IGp1bXBzIG92ZXIgMTMgbGF6eSBkb2dzLg==").as_bytes())),
87            tdef: TypeDef::bytes().fallible(),
88        }
89    ];
90}