vrl 0.32.0

Vector Remap Language
Documentation
use crate::compiler::prelude::*;
use bytes::Bytes;

fn uuid_v4() -> Value {
    let mut buf = [0; 36];
    let uuid = uuid::Uuid::new_v4().hyphenated().encode_lower(&mut buf);
    Bytes::copy_from_slice(uuid.as_bytes()).into()
}

#[derive(Clone, Copy, Debug)]
pub struct UuidV4;

impl Function for UuidV4 {
    fn identifier(&self) -> &'static str {
        "uuid_v4"
    }

    fn usage(&self) -> &'static str {
        "Generates a random [UUIDv4](https://en.wikipedia.org/wiki/Universally_unique_identifier#Version_4_(random)) string."
    }

    fn category(&self) -> &'static str {
        Category::Random.as_ref()
    }

    fn return_kind(&self) -> u16 {
        kind::BYTES
    }

    fn examples(&self) -> &'static [Example] {
        &[example! {
            title: "Create a UUIDv4",
            source: "uuid_v4()",
            result: Ok("1d262f4f-199b-458d-879f-05fd0a5f0683"),
            deterministic: false,
        }]
    }

    fn compile(
        &self,
        _state: &state::TypeState,
        _ctx: &mut FunctionCompileContext,
        _: ArgumentList,
    ) -> Compiled {
        Ok(UuidV4Fn.as_expr())
    }
}

#[derive(Debug, Clone, Copy)]
struct UuidV4Fn;

impl FunctionExpression for UuidV4Fn {
    fn resolve(&self, _: &mut Context) -> Resolved {
        Ok(uuid_v4())
    }

    fn type_def(&self, _: &TypeState) -> TypeDef {
        TypeDef::bytes().infallible()
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::value::Value;
    use std::collections::BTreeMap;

    test_type_def![default {
        expr: |_| { UuidV4Fn },
        want: TypeDef::bytes().infallible(),
    }];

    #[test]
    fn uuid_v4() {
        let mut state = state::RuntimeState::default();
        let mut object: Value = Value::Object(BTreeMap::new());
        let tz = TimeZone::default();
        let mut ctx = Context::new(&mut object, &mut state, &tz);
        let value = UuidV4Fn.resolve(&mut ctx).unwrap();

        assert!(matches!(&value, Value::Bytes(_)));

        match value {
            Value::Bytes(val) => {
                let val = String::from_utf8_lossy(&val);
                uuid::Uuid::parse_str(&val).expect("valid UUID V4");
            }
            _ => unreachable!(),
        }
    }
}