Serialization 如何编写用于检查Serde序列化和反序列化的通用函数?

Serialization 如何编写用于检查Serde序列化和反序列化的通用函数?,serialization,rust,lifetime,serde,Serialization,Rust,Lifetime,Serde,在一个涉及自定义Serde(1.0)序列化和反序列化方法的项目中,我依赖此测试例程来检查序列化对象并返回是否会产生等效对象 // let o: T = ...; let buf: Vec<u8> = to_vec(&o).unwrap(); let o2: T = from_slice(&buf).unwrap(); assert_eq!(o, o2); 这适用于拥有类型,但不适用于具有生存期边界()的类型: 错误: error[E0279]:未满足'for ser

在一个涉及自定义Serde(1.0)序列化和反序列化方法的项目中,我依赖此测试例程来检查序列化对象并返回是否会产生等效对象

// let o: T = ...;
let buf: Vec<u8> = to_vec(&o).unwrap();
let o2: T = from_slice(&buf).unwrap();
assert_eq!(o, o2);
这适用于拥有类型,但不适用于具有生存期边界()的类型:

错误:

error[E0279]:未满足'for serde::Deserialize'de:'的要求('expected bound life parameter'de,found concrete life`)
-->src/main.rs:25:5
|
25 | check|serde(&(“还有更多!”,36));//[E0279]
|     ^^^^^^^^^^^
|
=注:由于“`for`for`&str”的impl上的要求,需要`
=注意:由于对`(&str,{integer})的` for`的impl的要求,因此需要`
=注意:由于对`(&str,{integer})的`serde::de::DeserializeOwned`的impl有要求,因此需要`
=注:“检查”服务要求`
当然,我很茫然。我们如何使用Serde构建一个通用函数来序列化一个对象并将其反序列化回一个新对象?特别是,这个函数可以在Rust(稳定或夜间)中实现吗?如果可以,我的实现缺少哪些调整?

已经表明,如果没有泛型关联类型,我们无法有效地实现这一点。建立反序列化对象的深层所有权是我在这里描述的一项可能的工作

第三种尝试非常接近于一种灵活的解决方案,但由于工作方式的不同,它存在不足。该特征不适合检索对象的深层版本。例如,尝试使用ToOwned for
&str
的实现会给您带来另一个字符串片段

let a: &str = "hello";
let b: String = (&a).to_owned(); // expected String, got &str
同样,包含字符串片段的结构的
拥有的
类型不能是包含
字符串
s的结构。代码:

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Foo<'a>(&str, i32);

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct FooOwned(String, i32);
这里的目的是从任何东西中产生一个深度副本。似乎没有一个简单的全面实现,但有些技巧是可能的。首先,我们可以将它实现到
T:ToDeeplyOwned
中的所有引用类型

impl<'a, T: ?Sized + ToDeeplyOwned> ToDeeplyOwned for &'a T {
    type Owned = T::Owned;
    fn to_deeply_owned(&self) -> Self::Owned {
        (**self).to_deeply_owned()
    }
}
要使问题中的示例发挥作用,我们至少需要以下内容:

impl_deeply_owned!(i32);
impl_deeply_owned!(String);
impl_deeply_owned!(Vec<i32>);
impl_deeply_owned!(str, String);

不幸的是,您需要的是一个尚未在Rust中实现的特性:泛型关联类型

让我们看一下check\u serde的另一个变体:

pub fn check_serde<T>(o: T)
where
    for<'a> T: Debug + PartialEq<T> + Serialize + Deserialize<'a>,
{
    let buf: Vec<u8> = to_vec(&o).unwrap();
    let o2: T = from_slice(&buf).unwrap();
    assert_eq!(o, o2);
}

fn main() {
    check_serde("wait"); // [E0279]
}
简单(但有点笨拙)的解决方案:从函数外部提供
buf

pub fn check\u serde,
{
*buf=到_vec(o).展开();
设o2:T=从_切片(buf).展开();
断言(o和o);
}
buf
可以与
Cursor一起重用

pub fn用光标检查,
{
buf.clear();
让mut cursor=cursor::new(buf);
到_writer(&mut cursor,o)。展开();
设o2:T=从_切片(光标。进入_内部())。展开();
断言(o和o);
}

Arg我正是试图做到这一点。也许值得重新审视这个答案,因为我们应该有足够的GATs在夜间实施。不幸的是,即使经过一些调整,给定的代码也无法工作。是目前为止我能做的最好的了,它无法编译。
let a: &str = "hello";
let b: String = (&a).to_owned(); // expected String, got &str
#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct Foo<'a>(&str, i32);

#[derive(Debug, PartialEq, Serialize, Deserialize)]
struct FooOwned(String, i32);
pub trait ToDeeplyOwned {
    type Owned;
    fn to_deeply_owned(&self) -> Self::Owned;
}
impl<'a, T: ?Sized + ToDeeplyOwned> ToDeeplyOwned for &'a T {
    type Owned = T::Owned;
    fn to_deeply_owned(&self) -> Self::Owned {
        (**self).to_deeply_owned()
    }
}
macro_rules! impl_deeply_owned {
    ($t: ty, $t2: ty) => { // turn $t into $t2
        impl ToDeeplyOwned for $t {
            type Owned = $t2;
            fn to_deeply_owned(&self) -> Self::Owned {
                self.to_owned()
            }
        }
    };
    ($t: ty) => { // turn $t into itself, self-contained type
        impl ToDeeplyOwned for $t {
            type Owned = $t;
            fn to_deeply_owned(&self) -> Self::Owned {
                self.to_owned()
            }
        }
    };
}
impl_deeply_owned!(i32);
impl_deeply_owned!(String);
impl_deeply_owned!(Vec<i32>);
impl_deeply_owned!(str, String);
#[derive(Debug, PartialEq, Serialize)]
struct Foo<'a>(&'a str, i32);

#[derive(Debug, PartialEq, Clone, Deserialize)]
struct FooOwned(String, i32);

impl<'a> ToDeeplyOwned for Foo<'a> {
    type Owned = FooOwned;

    fn to_deeply_owned(&self) -> FooOwned {
        FooOwned(self.0.to_string(), self.1)
    }
}

impl<'a> PartialEq<FooOwned> for Foo<'a> {
    fn eq(&self, o: &FooOwned) -> bool {
        self.0 == o.0 && self.1 == o.1
    }
}

pub fn check_serde<'a, T: ?Sized>(o: &'a T)
where
    T: Debug + ToDeeplyOwned + PartialEq<<T as ToDeeplyOwned>::Owned> + Serialize,
    <T as ToDeeplyOwned>::Owned: Debug + DeserializeOwned,
{
    let buf: Vec<u8> = to_vec(&o).unwrap();
    let o2: T::Owned = from_slice(&buf).unwrap();
    assert_eq!(o, &o2);
}

// all of these are ok
check_serde(&5);
check_serde(&vec![1, 2, 5]);
check_serde(&"five".to_string());
check_serde("wait");
check_serde(&"wait");
check_serde(&Foo("There's more!", 36));
pub fn check_serde<T>(o: T)
where
    for<'a> T: Debug + PartialEq<T> + Serialize + Deserialize<'a>,
{
    let buf: Vec<u8> = to_vec(&o).unwrap();
    let o2: T = from_slice(&buf).unwrap();
    assert_eq!(o, o2);
}

fn main() {
    check_serde("wait"); // [E0279]
}
trait SerdeFamily {
    type Member<'a>: Debug + for<'b> PartialEq<Self::Member<'b>> + Serialize + Deserialize<'a>;
}

struct I32Family;
struct StrFamily;

impl SerdeFamily for I32Family {
    type Member<'a> = i32; // ignoring a parameter is allowed
}

impl SerdeFamily for StrFamily {
    type Member<'a> = &'a str;
}

pub fn check_serde<'a, Family>(o: Family::Member<'a>)
where
    Family: SerdeFamily,
{
    let buf: Vec<u8> = to_vec(&o).unwrap();
    // `o2` is of type `Family::Member<'b>`
    // with a lifetime 'b different from 'a
    let o2: Family::Member = from_slice(&buf).unwrap();
    assert_eq!(o, o2);
}

fn main() {
    check_serde::<I32Family>(5);
    check_serde::<StrFamily>("wait");
}