vrl/stdlib/
uuid_v4.rs

1use crate::compiler::prelude::*;
2use bytes::Bytes;
3
4fn uuid_v4() -> Value {
5    let mut buf = [0; 36];
6    let uuid = uuid::Uuid::new_v4().hyphenated().encode_lower(&mut buf);
7    Bytes::copy_from_slice(uuid.as_bytes()).into()
8}
9
10#[derive(Clone, Copy, Debug)]
11pub struct UuidV4;
12
13impl Function for UuidV4 {
14    fn identifier(&self) -> &'static str {
15        "uuid_v4"
16    }
17
18    fn usage(&self) -> &'static str {
19        "Generates a random [UUIDv4](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)) string."
20    }
21
22    fn category(&self) -> &'static str {
23        Category::Random.as_ref()
24    }
25
26    fn return_kind(&self) -> u16 {
27        kind::BYTES
28    }
29
30    fn examples(&self) -> &'static [Example] {
31        &[example! {
32            title: "Create a UUIDv4",
33            source: "uuid_v4()",
34            result: Ok("1d262f4f-199b-458d-879f-05fd0a5f0683"),
35            deterministic: false,
36        }]
37    }
38
39    fn compile(
40        &self,
41        _state: &state::TypeState,
42        _ctx: &mut FunctionCompileContext,
43        _: ArgumentList,
44    ) -> Compiled {
45        Ok(UuidV4Fn.as_expr())
46    }
47}
48
49#[derive(Debug, Clone, Copy)]
50struct UuidV4Fn;
51
52impl FunctionExpression for UuidV4Fn {
53    fn resolve(&self, _: &mut Context) -> Resolved {
54        Ok(uuid_v4())
55    }
56
57    fn type_def(&self, _: &TypeState) -> TypeDef {
58        TypeDef::bytes().infallible()
59    }
60}
61
62#[cfg(test)]
63mod tests {
64    use super::*;
65    use crate::value::Value;
66    use std::collections::BTreeMap;
67
68    test_type_def![default {
69        expr: |_| { UuidV4Fn },
70        want: TypeDef::bytes().infallible(),
71    }];
72
73    #[test]
74    fn uuid_v4() {
75        let mut state = state::RuntimeState::default();
76        let mut object: Value = Value::Object(BTreeMap::new());
77        let tz = TimeZone::default();
78        let mut ctx = Context::new(&mut object, &mut state, &tz);
79        let value = UuidV4Fn.resolve(&mut ctx).unwrap();
80
81        assert!(matches!(&value, Value::Bytes(_)));
82
83        match value {
84            Value::Bytes(val) => {
85                let val = String::from_utf8_lossy(&val);
86                uuid::Uuid::parse_str(&val).expect("valid UUID V4");
87            }
88            _ => unreachable!(),
89        }
90    }
91}