vrl/stdlib/
strip_ansi_escape_codes.rs1use crate::compiler::prelude::*;
2use bytes::Bytes;
3
4fn strip_ansi_escape_codes(bytes: Value) -> Resolved {
5 let bytes = bytes.try_bytes()?;
6 let stripped_bytes = Bytes::from(strip_ansi_escapes::strip(&bytes));
7 Ok(stripped_bytes.into())
8}
9
10#[derive(Clone, Copy, Debug)]
11pub struct StripAnsiEscapeCodes;
12
13impl Function for StripAnsiEscapeCodes {
14 fn identifier(&self) -> &'static str {
15 "strip_ansi_escape_codes"
16 }
17
18 fn usage(&self) -> &'static str {
19 "Strips [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code) from `value`."
20 }
21
22 fn category(&self) -> &'static str {
23 Category::String.as_ref()
24 }
25
26 fn return_kind(&self) -> u16 {
27 kind::BYTES
28 }
29
30 fn parameters(&self) -> &'static [Parameter] {
31 const PARAMETERS: &[Parameter] = &[Parameter::required(
32 "value",
33 kind::BYTES,
34 "The string to strip.",
35 )];
36 PARAMETERS
37 }
38
39 fn examples(&self) -> &'static [Example] {
40 &[]
41 }
42
43 fn compile(
44 &self,
45 _state: &state::TypeState,
46 _ctx: &mut FunctionCompileContext,
47 arguments: ArgumentList,
48 ) -> Compiled {
49 let value = arguments.required("value");
50
51 Ok(StripAnsiEscapeCodesFn { value }.as_expr())
52 }
53}
54
55#[derive(Debug, Clone)]
56struct StripAnsiEscapeCodesFn {
57 value: Box<dyn Expression>,
58}
59
60impl FunctionExpression for StripAnsiEscapeCodesFn {
61 fn resolve(&self, ctx: &mut Context) -> Resolved {
62 let bytes = self.value.resolve(ctx)?;
63
64 strip_ansi_escape_codes(bytes)
65 }
66
67 fn type_def(&self, _: &state::TypeState) -> TypeDef {
68 TypeDef::bytes().infallible()
72 }
73}
74
75#[cfg(test)]
76mod tests {
77 use super::*;
78
79 test_function![
80 strip_ansi_escape_codes => StripAnsiEscapeCodes;
81
82 no_codes {
83 args: func_args![value: "foo bar"],
84 want: Ok("foo bar"),
85 tdef: TypeDef::bytes().infallible(),
86 }
87
88 strip_1 {
89 args: func_args![value: "\x1b[3;4Hfoo bar"],
90 want: Ok("foo bar"),
91 tdef: TypeDef::bytes().infallible(),
92 }
93
94 strip_2 {
95 args: func_args![value: "\x1b[46mfoo\x1b[0m bar"],
96 want: Ok("foo bar"),
97 tdef: TypeDef::bytes().infallible(),
98 }
99
100 strip_3 {
101 args: func_args![value: "\x1b[=3lfoo bar"],
102 want: Ok("foo bar"),
103 tdef: TypeDef::bytes().infallible(),
104 }
105 ];
106}