Repository: nushell/nushell
File: crates/nu-command/src/random/uuid.rs (Rust)

Code before:
            let uuid = Uuid::new_v7(ts);
            uuid.hyphenated().to_string()
        }
        _ => {
            return Err(ShellError::GenericError {
                error: format!(
                    "Unsupported UUID version: {}. Supported versions are 1, 3, 4, 5, and 7.",
                    version
                ),
                msg: "Invalid UUID version".to_string(),
                span: Some(span),
                help: Some("Specify version with -v: 1, 3, 4, 5, or 7".to_string()),
                inner: Vec::new(),
            });
        }
    };

    Ok(PipelineData::Value(Value::string(uuid_str, span), None))
}

fn random_mac_address() -> [u8; 6] {
    let mut mac = [0u8; 6];
    mac.iter_mut().for_each(|byte| *byte = rand::random());
    mac[0] |= 0x01;
    mac
}

fn get_namespace_and_name(
    engine_state: &EngineState,
    stack: &mut Stack,
    call: &Call,
    span: Span,
) -> Result<(Uuid, String), ShellError> {
    let namespace_str: Option<String> = call.get_flag(engine_state, stack, "namespace")?;
    let name: Option<String> = call.get_flag(engine_state, stack, "name")?;

    let namespace_str = match namespace_str {
        Some(ns) => ns,
        None => {
            return Err(ShellError::MissingParameter {
                param_name: "namespace".to_string(),
                span,
            });
        }
    };

    let name = match name {
        Some(n) => n,
        None => {
            return Err(ShellError::MissingParameter {
                param_name: "name".to_string(),

Review comment (suggestion):
Is it following the spirit of the `UUIDv1` specification when the MAC address is randomly generated? (even if tagging it by MAC can be bad in other ways)

https://en.wikipedia.org/wiki/Universally_unique_identifier#Versions_1_and_6_(date-time_and_MAC_address)

If it is too much effort to provide a sane implementation, I would say we rather omit it or maybe let the user supply it like for the namespace ones.



Code after:
            uuid.hyphenated().to_string()
        }
        4 => {
            let uuid = Uuid::new_v4();
            uuid.hyphenated().to_string()
        }
        5 => {
            let (namespace, name) = get_namespace_and_name(engine_state, stack, call, span)?;
            let uuid = Uuid::new_v5(&namespace, name.as_bytes());
            uuid.hyphenated().to_string()
        }
        7 => {
            let ts = Timestamp::now(uuid::timestamp::context::NoContext);
            let uuid = Uuid::new_v7(ts);
            uuid.hyphenated().to_string()
        }
        _ => {
            return Err(ShellError::IncorrectValue {
                msg: format!(
                    "Unsupported UUID version: {}. Supported versions are 1, 3, 4, 5, and 7.",
                    version
                ),
                val_span: span,
                call_span: span,
            });
        }
    };

    Ok(PipelineData::Value(Value::string(uuid_str, span), None))
}

fn validate_flags(
    engine_state: &EngineState,
    stack: &mut Stack,
    call: &Call,
    span: Span,
    version: i64,
) -> Result<(), ShellError> {
    match version {
        1 => {
            if call
                .get_flag::<Option<String>>(engine_state, stack, "namespace")?
                .is_some()
            {
                return Err(ShellError::IncompatibleParametersSingle {
                    msg: "version 1 uuid does not take namespace as a parameter".to_string(),
                    span,
                });
            }
            if call
                .get_flag::<Option<String>>(engine_state, stack, "name")?