vrl/stdlib/
get_env_var.rs1use crate::compiler::prelude::*;
2
3fn get_env_var(value: &Value) -> Resolved {
4 let name = value.try_bytes_utf8_lossy()?;
5 std::env::var(name.as_ref())
6 .map(Into::into)
7 .map_err(|e| e.to_string().into())
8}
9
10#[derive(Clone, Copy, Debug)]
11pub struct GetEnvVar;
12
13impl Function for GetEnvVar {
14 fn identifier(&self) -> &'static str {
15 "get_env_var"
16 }
17
18 fn usage(&self) -> &'static str {
19 "Returns the value of the environment variable specified by `name`."
20 }
21
22 fn category(&self) -> &'static str {
23 Category::System.as_ref()
24 }
25
26 fn internal_failure_reasons(&self) -> &'static [&'static str] {
27 &[
28 "Environment variable `name` does not exist.",
29 "The value of environment variable `name` is not valid Unicode",
30 ]
31 }
32
33 fn return_kind(&self) -> u16 {
34 kind::BYTES
35 }
36
37 fn parameters(&self) -> &'static [Parameter] {
38 const PARAMETERS: &[Parameter] = &[Parameter::required(
39 "name",
40 kind::BYTES,
41 "The name of the environment variable.",
42 )];
43 PARAMETERS
44 }
45
46 fn examples(&self) -> &'static [Example] {
47 &[example! {
48 title: "Get an environment variable",
49 source: r#"get_env_var!("HOME")"#,
50 result: Ok("/root"),
51 deterministic: false,
52 }]
53 }
54
55 fn compile(
56 &self,
57 _state: &state::TypeState,
58 _ctx: &mut FunctionCompileContext,
59 arguments: ArgumentList,
60 ) -> Compiled {
61 let name = arguments.required("name");
62
63 Ok(GetEnvVarFn { name }.as_expr())
64 }
65}
66
67#[derive(Debug, Clone)]
68struct GetEnvVarFn {
69 name: Box<dyn Expression>,
70}
71
72impl FunctionExpression for GetEnvVarFn {
73 fn resolve(&self, ctx: &mut Context) -> Resolved {
74 let value = self.name.resolve(ctx)?;
75 get_env_var(&value)
76 }
77
78 fn type_def(&self, _: &state::TypeState) -> TypeDef {
79 TypeDef::bytes().fallible()
80 }
81}
82
83#[cfg(test)]
84mod tests {
85 use super::*;
86 use crate::value;
87
88 test_function![
89 get_env_var => GetEnvVar;
90
91 before_each => {
92 unsafe { std::env::set_var("VAR2", "var") };
94 }
95
96 doesnt_exist {
97 args: func_args![name: "VAR1"],
98 want: Err("environment variable not found"),
99 tdef: TypeDef::bytes().fallible(),
100 }
101
102 exists {
103 args: func_args![name: "VAR2"],
104 want: Ok(value!("var")),
105 tdef: TypeDef::bytes().fallible(),
106 }
107
108 invalid1 {
109 args: func_args![name: "="],
110 want: Err("environment variable not found"),
111 tdef: TypeDef::bytes().fallible(),
112 }
113
114 invalid2 {
115 args: func_args![name: ""],
116 want: Err("environment variable not found"),
117 tdef: TypeDef::bytes().fallible(),
118 }
119
120 invalid3 {
121 args: func_args![name: "a=b"],
122 want: Err("environment variable not found"),
123 tdef: TypeDef::bytes().fallible(),
124 }
125 ];
126}