Rust 如何将一个以特征为边界的类型传递给Serde';s与反序列化?

Rust 如何将一个以特征为边界的类型传递给Serde';s与反序列化?,rust,deserialization,traits,serde,Rust,Deserialization,Traits,Serde,满足MyTrait的类型应该被传递给反序列化\u数据,该数据由反序列化\u与指定。这是我的: 使用serde::{反序列化,反序列化程序};//1.0.117 使用serde_json;//1.0.59 类型项=结果; 酒吧特质我的特质{ fn方法(ind:&str)->项目; } #[导出(反序列化)] 发布结构 哪里 T:MyTrait+?size,//打算将满足“MyTrait”的类型T传递给函数“反序列化\u数据”, { #[serde(使用=“反序列化数据”)] //#[serde(绑

满足
MyTrait
的类型应该被传递给
反序列化\u数据
,该数据由
反序列化\u与
指定。这是我的:

使用serde::{反序列化,反序列化程序};//1.0.117
使用serde_json;//1.0.59
类型项=结果;
酒吧特质我的特质{
fn方法(ind:&str)->项目;
}
#[导出(反序列化)]
发布结构
哪里
T:MyTrait+?size,//打算将满足“MyTrait”的类型T传递给函数“反序列化\u数据”,
{
#[serde(使用=“反序列化数据”)]
//#[serde(绑定(反序列化=“T:MyTrait,for”))]
发布数据:字符串,
}
fn反序列化_数据,
{
让ind=::反序列化(d).unwrap();
匹配T::方法(ind){
正常(数据)=>正常(数据),
Err(e)=>Err(serde::de::Error::custom(格式参数)(“无效类型”),
}
}
结构A;
将MyTrait用于{
fn方法(_ind:&str)->项目{
//为了简单起见,返回常量
Ok(“方法“.to_string())
}
}
fn main(){
设s=r#“{”data:“string”}”;
让ob:S=serde_json::from_str(S).unwrap();
}
编译器抱怨:

错误[E0392]:从未使用参数'T'
-->src/main.rs:10:14
|
10 |酒吧结构
|^未使用的参数
|
=帮助:考虑删除“T”,在字段中引用它,或者使用标记,例如“幻像”。
我确实使用了
T
,而
PhantomData
没有多大帮助。
一个明显的方法是使用
struct A
及其实现方法作为板条箱或其他东西,然后导入它们。不幸的是,这不适用于我的情况,因此我试图将结构类型传递给
反序列化\u数据
,并实现这一点。

要编译代码,您需要:

  • struct S
    中使用
    T
    ,例如使用
    PhantomData
  • 使用turbofish操作符将
    T
    显式传递到
    反序列化\u数据
  • 反序列化_data()
    中的
    T
    泛型类型添加适当的特征边界,例如
    MyTrait
例如():

#[派生(反序列化)]
发布结构
哪里
T:MyTrait+?尺寸,
{
#[serde(用=“反序列化数据:”)反序列化数据]
发布数据:字符串,
marker:std::marker::PhantomData,
}
fn反序列化_数据,
T:MyTrait+?尺寸,
{
// ...
}

要编译代码,您需要:

  • struct S
    中使用
    T
    ,例如使用
    PhantomData
  • 使用turbofish操作符将
    T
    显式传递到
    反序列化\u数据
  • 反序列化_data()
    中的
    T
    泛型类型添加适当的特征边界,例如
    MyTrait
例如():

#[派生(反序列化)]
发布结构
哪里
T:MyTrait+?尺寸,
{
#[serde(用=“反序列化数据:”)反序列化数据]
发布数据:字符串,
marker:std::marker::PhantomData,
}
fn反序列化_数据,
T:MyTrait+?尺寸,
{
// ...
}

听起来你的问题会在下一步得到解决。听起来你的问题会在下一步得到解决
use serde::{Deserialize, Deserializer}; // 1.0.117
use serde_json; // 1.0.59

type Item = Result<String, Box<dyn std::error::Error + Send + Sync>>;
pub trait MyTrait {
    fn method(ind: &str) -> Item;
}

#[derive(Deserialize)]
pub struct S<T>
where
    T: MyTrait + ?Sized, // intend to pass a type T satisfying `MyTrait` to function `deserialize_data`,
{
    #[serde(deserialize_with = "deserialize_data")]
    //#[serde(bound( deserialize = "T: MyTrait,  for<'de2> T: Deserialize<'de2>" ))]
    pub data: String,
}

fn deserialize_data<'de, D, T>(d: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
{
    let ind = <&str>::deserialize(d).unwrap();
    match T::method(ind) {
        Ok(data) => Ok(data),
        Err(e) => Err(serde::de::Error::custom(format_args!("invalid type."))),
    }
}

struct A;
impl MyTrait for A {
    fn method(_ind: &str) -> Item {
        // to make it simple, return constant
        Ok("method".to_string())
    }
}

fn main() {
    let s = r#"{"data": "string"}"#;
    let ob: S<A> = serde_json::from_str(s).unwrap();
}
#[derive(Deserialize)]
pub struct S<T>
where
    T: MyTrait + ?Sized,
{
    #[serde(deserialize_with = "deserialize_data::<_, T>")]
    pub data: String,
    marker: std::marker::PhantomData<T>,
}

fn deserialize_data<'de, D, T>(d: D) -> Result<String, D::Error>
where
    D: Deserializer<'de>,
    T: MyTrait + ?Sized,
{
    // ...
}