Skip to content

[Rust] Map key encode as human-readable, but decoded as raw #8438

Open
@koxu1996

Description

@koxu1996

Reproducible example

use std::collections::HashMap;

use serde::{Serialize, Deserialize, Serializer, Deserializer};
use flexbuffers::{self, FlexbufferSerializer, Reader};

#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Hash)]
struct User(String);

impl User {
  fn to_bytes(&self) -> Vec<u8> {
    self.0.clone().into_bytes()
  }

  fn from_bytes(bytes: &[u8]) -> Self {
    User(String::from_utf8_lossy(bytes).into_owned())
  }
}

impl Serialize for User {
  fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
    if serializer.is_human_readable() {
      println!("Serializing as human readable string");
      serializer.serialize_str(&hex::encode(self.to_bytes()))
    } else {
      println!("Serializing as raw bytes");
      serializer.serialize_bytes(&self.to_bytes())
    }
  }
}

impl<'de> Deserialize<'de> for User {
  fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
    if deserializer.is_human_readable() && false {
      println!("Deserializing as human readable string");
      let hex_string = String::deserialize(deserializer)?;
      let bytes = hex::decode(&hex_string).map_err(serde::de::Error::custom)?;
      Ok(User::from_bytes(&bytes))
    } else {
      println!("Deserializing as raw bytes");
      let bytes = <Vec<u8>>::deserialize(deserializer)?;
      Ok(User::from_bytes(&bytes))
    }
  }
}

#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
struct TestStruct {
  map: HashMap<User, u32>,
}

fn main() {
  // Prepare test data.
  let mut map = HashMap::new();
  map.insert(User("john".to_string()), 100);
  let test_struct = TestStruct { map };

  // Serialize using flexbuffers.
  let mut serializer = FlexbufferSerializer::new();
  test_struct.serialize(&mut serializer).unwrap();
  let serialized_data = serializer.take_buffer();

  // Deserialize back.
  let reader = Reader::get_root(serialized_data.as_slice()).unwrap();
  let deserialized_struct = TestStruct::deserialize(reader).expect("Deserialization should not fail");
}

Output

Serializing as human readable string
Deserializing as raw bytes
thread 'main' panicked at src/main.rs:64:61:
Deserialization should not fail: Serde("invalid type: string \"6a6f686e\", expected a sequence")
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions