trainlog/tui/src/id.c

56 lines
1.9 KiB
C

/**
* @file id.c
* @brief Trainlog UUIDv4 identifier generation.
*/
#include "trainlog/id.h"
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <uuid/uuid.h>
static bool prefix_is_supported(const char *prefix) {
/*
* Keep official creator prefixes deliberately small and explicit.
* The exchange parser remains more permissive because imported v1 IDs are
* opaque values governed by the frozen wire-schema syntax.
*/
return strcmp(prefix, "ex") == 0 || strcmp(prefix, "se") == 0 || strcmp(prefix, "bo") == 0 ||
strcmp(prefix, "sy") == 0 || strcmp(prefix, "sxe") == 0 || strcmp(prefix, "sp") == 0 ||
strcmp(prefix, "spr") == 0 || strcmp(prefix, "spe") == 0 || strcmp(prefix, "spd") == 0 ||
strcmp(prefix, "spw") == 0 || strcmp(prefix, "pgr") == 0 || strcmp(prefix, "del") == 0 ||
strcmp(prefix, "sl") == 0 || strcmp(prefix, "slr") == 0 || strcmp(prefix, "sle") == 0 ||
strcmp(prefix, "med") == 0 || strcmp(prefix, "medr") == 0 || strcmp(prefix, "mdi") == 0;
}
TrainlogStatus trainlog_id_generate(const char *prefix, char *output, size_t output_size) {
uuid_t value;
char uuid_text[TRAINLOG_UUID_TEXT_LENGTH + 1U];
int written;
if (prefix == NULL || output == NULL) {
return TRAINLOG_STATUS_INVALID_ARGUMENT;
}
if (!prefix_is_supported(prefix) ||
output_size < strlen(prefix) + 1U + TRAINLOG_UUID_TEXT_LENGTH + 1U) {
return TRAINLOG_STATUS_INVALID_ARGUMENT;
}
/*
* libuuid's uuid_generate_random() creates a random RFC 4122 UUID with the
* version and variant bits set appropriately for UUID version 4.
*/
uuid_generate_random(value);
uuid_unparse_lower(value, uuid_text);
written = snprintf(output, output_size, "%s_%s", prefix, uuid_text);
if (written < 0 || (size_t)written >= output_size) {
return TRAINLOG_STATUS_SYSTEM_ERROR;
}
return TRAINLOG_STATUS_OK;
}