es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo puedo devolver una cadena formateada desde una macro de rust?

Estoy intentando lograr algo como esto:

Construir un mensaje de error con algunas variables capturadas;
Registrar este mensaje de error;
Guardar y devolver este mensaje de error al usuario eventualmente;

Aparentemente esto se puede hacer en pocas líneas de código, pero es un poco tedioso porque necesito este patrón en todas partes de mi proyecto, como se muestra a continuación:

let vara = 233;
let err = format!("mensaje de error personalizado, vara: {}", var_a);

// Aquí registro el error con los macros tokio-rs/tracing.
error!(err = %err, "mensaje de error personalizado");

// Los errores se mostrarán eventualmente al usuario final.
serrs.append(err);

Estoy tratando de lograr esto con un macro que envuelve los macros tokio-rs/tracing pero devuelve el mensaje de error construido:


[macro_export] macrorules! logusr_err { ($($arg:tt)+) => ( error!($($arg)+) format!($($arg)+) ); }

Así que puedo usar este macro en mi proyecto para simplificar un poco el código:

let err = logusrerr!("mensaje de error personalizado, {}", vara = vara);

// Los errores se mostrarán eventualmente al usuario final.
serrs.append(err);

pero me he quedado atascado en el error de compilación:

Error: la expansión del macro ignora el token format y cualquier cosa siguiente.

¿Cómo debo devolver la cadena formateada desde mi macro log_urs_err!?

Porque en el futuro quiero incluir la información precisa de la ubicación del archivo y la línea también en mis registros, por lo que creo que la macro es la dirección correcta a seguir, o hay algún enfoque mejor?

Tags:  

Answer

  1. Avatar for davy.ai

    Se puede lograr esto utilizando la macro format_args!. Esta macro te permite pasar una cadena de formato y una lista de argumentos para que sean formateados. La macro devolverá una estructura std::fmt::Arguments que se puede utilizar para construir la cadena formateada.

    Por ejemplo, se puede utilizar la siguiente macro para registrar el mensaje de error y devolver la cadena formateada:

    #[macro_export]
    macro_rules! log_usr_err {
        ($($arg:tt)+) => (
            let err = format_args!($($arg)+);
            error!(err = %err, "some custom error message");
            err
        );
    }
    

    De esta manera, se puede utilizar la macro para registrar el mensaje de error y devolver la cadena formateada:

    let err = log_usr_err!("some custom error message, {}", var_a);
    
    // Los errores serán eventualmente mostrados a los usuarios finales
    serrs.append(err);
    

Comments are closed.