简体   繁体   English

Rust 中 Borsh 序列化/反序列化方法的包装

[英]Wrapper over Borsh Serialization/Deserialization methods in Rust

I have a struct A which implements BorshDeserialize and BorshSerialize as follows我有一个结构 A 实现 BorshDeserialize 和 BorshSerialize 如下

#[derive(Clone, PartialEq, Eq, BorshSerialize, BorshDeserialize)]
struct A {
   a : i32,
   b:  String,
}

I know I can serialize or deserialize A when I do the following:-我知道我可以在执行以下操作时序列化或反序列化 A:-

let s = A {a: 1 , b: "a".to_string()};

// Serialize 
let serialzed_data = s.try_to_vec().unwrap()

// Deserialize
deserialized_struct = A::try_from_slice(&serialzed_data).unwrap();

I am trying to wrap over these two methods by creating two general traits on main.rs where I import this struct from another file a.rs.我试图通过在 main.rs 上创建两个通用特征来覆盖这两种方法,我从另一个文件 a.rs 导入这个结构。

pub trait Serializable<T: BorshSerialize> {
    fn serialize(s: T) -> Vec<u8> {
        s.try_to_vec().unwrap()
    }
}

pub trait Deserializable<T : BorshDeserialize> {
    fn deserialize(s: &[u8]) -> Result<T, ()> {
        let deserialized_val = match T::try_from_slice(&s) {
            Ok(val) => {val},
            Err(_) => {return Err(());},
        };
        Ok(deserialized_val)
    }
}

where I implement Serialize and Deserialize for A as follows on a.rs我在 a.rs 上为 A 实现序列化和反序列化,如下所示

impl Serializable<A> for A {}
impl Deserializable<A> for A {}

But in the source code when I call the method serialize on A for this instruction,但是在源代码中,当我为此指令在 A 上调用方法序列化时,

A::serialize(&some_instance_of_A).unwrap()

I get the following error我收到以下错误

A::serialize(&some_instance_of_A).unwrap()
   ^^^^^^^^^ multiple `serialize` found
   |
   = note: candidate #1 is defined in an impl of the trait `Serializable` for the type `A`
   = note: candidate #2 is defined in an impl of the trait `BorshSerialize` for the type `A`

help: disambiguate the associated function for candidate #1
   |
46 |   <&Self as A::Serializable>::serialize(&some_instance_of_A), // TODO. See issue #64
   |                                    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
help: disambiguate the associated function for candidate #2
   |
46 |   <&A as BorshSerialize>::serialize(&some_instance_of_A).concat(), // TODO. See issue #64
   |

I understand that the compiler gets confused by the two instances of serialization schemes created(one due to Borsh from derive macro and the other from Serialize trait on main.rs).我知道编译器对创建的两个序列化方案实例感到困惑(一个是由于派生宏的 Borsh 而另一个是 main.rs 上的 Serialize trait)。 Is there a way to directly make the serialize call fall to BorshSerialize by default when A::serialize is called.有没有办法在调用 A::serialize 时直接使序列化调用默认为 BorshSerialize。

By preventing to import the BorshSerialize trait you can get rid of the error.通过阻止导入BorshSerialize特征,您可以摆脱错误。

With only the Serializable trait in scope, only one method can be called:只有 scope 中的Serializable trait,只能调用一种方法:

#[derive(Clone, PartialEq, Eq, borsh::BorshSerialize, borsh::BorshDeserialize)]
struct A {
    a : i32,
    b:  String,
}

impl Serializable for A {}

fn main() {
    let a = A { a: 0, b: String::from("") };
    let vec = a.serialize();
    eprintln!("{:?}", vec);
}

pub trait Serializable: borsh::BorshSerialize {
    fn serialize(&self) -> Vec<u8> {
        self.try_to_vec().unwrap()
    }
}

pub trait Deserializable<T : borsh::BorshDeserialize> {
    fn deserialize(s: &[u8]) -> Result<T, ()> {
        let deserialized_val = match T::try_from_slice(&s) {
            Ok(val) => {val},
            Err(_) => {return Err(());},
        };
        Ok(deserialized_val)
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM