vrl/stdlib/
encode_zstd.rs1use crate::compiler::prelude::*;
2use nom::AsBytes;
3use std::sync::LazyLock;
4
5static DEFAULT_COMPRESSION_LEVEL: LazyLock<Value> = LazyLock::new(|| Value::Integer(3));
6
7static PARAMETERS: LazyLock<Vec<Parameter>> = LazyLock::new(|| {
8 vec![
9 Parameter::required("value", kind::BYTES, "The string to encode."),
10 Parameter::optional(
11 "compression_level",
12 kind::INTEGER,
13 "The default compression level.",
14 )
15 .default(&DEFAULT_COMPRESSION_LEVEL),
16 ]
17});
18
19fn encode_zstd(value: Value, compression_level: Value) -> Resolved {
20 #[allow(clippy::cast_possible_truncation)] let compression_level = compression_level.try_integer()? as i32;
22
23 let value = value.try_bytes()?;
24 let encoded_bytes = zstd::encode_all(value.as_bytes(), compression_level)
26 .expect("zstd compression failed, please report");
27
28 Ok(Value::Bytes(encoded_bytes.into()))
29}
30
31#[derive(Clone, Copy, Debug)]
32pub struct EncodeZstd;
33
34impl Function for EncodeZstd {
35 fn identifier(&self) -> &'static str {
36 "encode_zstd"
37 }
38
39 fn usage(&self) -> &'static str {
40 "Encodes the `value` to [Zstandard](https://facebook.github.io/zstd)."
41 }
42
43 fn category(&self) -> &'static str {
44 Category::Codec.as_ref()
45 }
46
47 fn return_kind(&self) -> u16 {
48 kind::BYTES
49 }
50
51 fn examples(&self) -> &'static [Example] {
52 &[example! {
53 title: "Encode to Zstd",
54 source: r#"encode_base64(encode_zstd("please encode me"))"#,
55 result: Ok("KLUv/QBYgQAAcGxlYXNlIGVuY29kZSBtZQ=="),
56 }]
57 }
58
59 fn compile(
60 &self,
61 _state: &state::TypeState,
62 _ctx: &mut FunctionCompileContext,
63 arguments: ArgumentList,
64 ) -> Compiled {
65 let value = arguments.required("value");
66 let compression_level = arguments.optional("compression_level");
67
68 Ok(EncodeZstdFn {
69 value,
70 compression_level,
71 }
72 .as_expr())
73 }
74
75 fn parameters(&self) -> &'static [Parameter] {
76 PARAMETERS.as_slice()
77 }
78}
79
80#[derive(Clone, Debug)]
81struct EncodeZstdFn {
82 value: Box<dyn Expression>,
83 compression_level: Option<Box<dyn Expression>>,
84}
85
86impl FunctionExpression for EncodeZstdFn {
87 fn resolve(&self, ctx: &mut Context) -> Resolved {
88 let value = self.value.resolve(ctx)?;
89
90 let compression_level = self
91 .compression_level
92 .map_resolve_with_default(ctx, || DEFAULT_COMPRESSION_LEVEL.clone())?;
93
94 encode_zstd(value, compression_level)
95 }
96
97 fn type_def(&self, _: &state::TypeState) -> TypeDef {
98 TypeDef::bytes().infallible()
99 }
100}