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.

Deserializar una lista JSON de cadenas hexadecimales como bytes

Estoy tratando de leer un flujo JSON, parte del cual se ve así:

json
  "data": [
    "c1a8f800a4393e0cacd05a5bc60ae3e0",
    "bbac4013c1ca3482155b584d35dac185",
    "685f237d4fcbd191c981b94ef6986cde",
    "a08898e81f1ddb6612aa12641b856aa9"
  ]

(hay más entradas en la lista “data” y cada entrada es más larga, pero esto debería ser ilustrativo; tanto la longitud de la lista como la longitud de cada cadena hexadecimal se conocen en tiempo de compilación)

Idealmente, me gustaría tener un solo [u8; 64] (el tamaño real se conoce en tiempo de compilación), o en caso contrario, un Vec<u8>, pero imagino que sería más fácil deserializarlo como un Vec<[u8; 16]> y luego fusionarlos posteriormente. Sin embargo, estoy teniendo problemas incluso para hacer eso.

La librería hex tiene una forma de deserializar una única cadena hexadecimal como un Vec o un arreglo de u8, pero no puedo averiguar cómo decirle a Serde que haga eso para cada entrada de la lista. ¿Hay alguna manera sencilla de hacerlo que esté pasando por alto, o necesito escribir mi propio deserializador de listas?

Tags:  ,

Answer

  1. Avatar for davy.ai

    Para deserializar una lista de cadenas hexadecimales como Vec<[u8; 16]>, puedes usar el paquete serde_bytes en combinación con el paquete hex.

    Primero, agrega las siguientes dependencias a tu archivo Cargo.toml:

    [dependencies]
    serde = { version = "1.0", features = ["derive"] }
    serde_bytes = "0.11"
    hex = "0.4"
    

    Luego, puedes definir tu estructura de la siguiente manera:

    use serde::{Deserialize, Serialize};
    use serde_bytes::ByteBuf;
    use hex::FromHex;
    
    #[derive(Debug, Deserialize, Serialize)]
    struct Data {
        #[serde(deserialize_with = "deserialize_hex_list")]
        data: Vec<[u8; 16]>,
    }
    
    fn deserialize_hex_list<'de, D>(deserializer: D) -> Result<vec<[u8; 16]="">, D::Error>
    where
        D: serde::Deserializer<'de>,
    {
        let hex_strings: Vec<string> = Vec::deserialize(deserializer)?;
        let bytes: Result<vec<_>, _> = hex_strings
            .iter()
            .map(|hex_string| Vec::from_hex(hex_string))
            .collect();
        let bytes = bytes.map_err(serde::de::Error::custom)?;
        let hex_arrays: Vec<_> = bytes
            .into_iter()
            .map(|byte_array| {
                let mut hex_array = [0; 16];
                hex_array.copy_from_slice(&byte_array[..]);
                hex_array
            })
            .collect();
        Ok(hex_arrays)
    }
    

    Esto define una estructura Data con un campo data, que se deserializa usando la función deserialize_hex_list. Esta función primero deserializa la lista de cadenas hexadecimales como un Vec<string>, luego convierte cada cadena hexadecimal a un Vec<u8> usando el método from_hex del paquete hex, y finalmente convierte cada Vec<u8> en un arreglo [u8; 16].

    Ten en cuenta que esta implementación asume que cada cadena hexadecimal tiene una longitud de 32 caracteres (16 bytes en representación hexadecimal), y que la longitud de la lista se conoce en tiempo de compilación. Si estas suposiciones no son válidas para tu caso de uso, es posible que necesites modificar el código en consecuencia.</vec<_></vec<[u8;>

Comments are closed.