I have the following struct:
#[derive(Serialize, Deserialize)]
pub(crate) struct Item {
pub id: u32,
pub path: Vec<u8>
}
impl Item {
pub fn path_as_str(&self) -> String {
return GBK.decode(self.path.as_slice(), DecoderTrap::Strict).unwrap();
}
}
I have to read some binary files and parse them into this struct, I'm using bincode2
for it, and it works great, the problem is that once I have these items, I need to save them in a json format in another file, the problem is that path
is a UTF-16 String stored as raw bytes in the binary file, an I need it as a String in the json file, I've managed to do it by implementing the path_as_str
method and generating the json manually, but it's not ideal since I need to do this for multiple data structures and this operation needs to be done in a reverse order as well, Binary -> Json and Json -> Binary, I've tried to play around with custom Serializers, but I can't find a way make it work. For instance, how do I know from the serialize method that I'm serializing from a json file and not from the binary? Is it even possibile? I've read this answer but it doesn't seem to work as of now.
I'm new to rust, and as of now, I'm just looking for the right tool that suits better my needs for this project, I've done it in javascript, but I don't exactly trust javascript for the job since I'll need to deal with very low level bitwise operations.
Here is an example of the custom WString type that I was trying to implement:
use std::{fmt};
use encoding::{all::GBK, Encoding, DecoderTrap, EncoderTrap};
use serde::{Deserialize, Serialize, Serializer, de::{self, Visitor}, Deserializer};
#[derive(Debug)]
pub struct WString(Vec<u8>);
impl Serialize for WString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
// From here HOW can I know if I'am serializing to a json or to a binary file
let gbkValue = GBK.encode(self.0, EncoderTrap::Strict).unwrap();
return serializer.serialize_str(gbkValue);
}
}
impl<'de> Deserialize<'de> for WString {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>
{
// From here HOW can I know if I'm deserializing from a string or from the binary file?
deserializer.deserialize_string(WStringVisitor)
}
}
struct WStringVisitor;
impl<'de> Visitor<'de> for WStringVisitor {
type Value = WString;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("Expected a string")
}
fn visit_string<E>(self, value: String) -> Result<Self::Value, E>
where
E: de::Error,
{
let gbkValue = GBK.decode(value.as_bytes(), DecoderTrap::Strict).unwrap();
Ok(WString(gbkValue))
}
}