借用 serde-reflection 的检查器问题

Borrow checker problems with serde-reflection

我正在尝试使用 serde-reflection 创建一个 JSON 结构来解释 struct 结构,以便传输和接收结构作为 JavaScript 和 ArrayBuffer 然后在浏览器中将其反序列化为 JavaScript 对象。

我想要一种方法来“注册”我感兴趣的结构,然后跟踪所有这些已注册的类型,以便它们可以从 Web 服务器返回。

extern crate serde_json;
use serde_json::json;

use serde_reflection::{Samples, Tracer, TracerConfig};

pub struct MessageRegistry {
    tracer: Tracer,
    samples: Samples
}

impl MessageRegistry {
    pub fn new() -> MessageRegistry {
        MessageRegistry {
            tracer: Tracer::new(TracerConfig::default()),
            samples: Samples::new()
        }
    }

    pub fn add_type<T>(&mut self) {
        self.tracer.trace_type::<T>(&self.samples).unwrap();
                  //^^^^^^^^^^ the trait `serde::Deserialize<'_>` is not implemented for `T`
    }

    pub fn to_json_string(&mut self) -> String {
        let registry = self.tracer.registry().unwrap();
        serde_json::to_string(&registry).unwrap()
    }
}

我坚持使用 tracer.trace_type::<T>(&self.samples) 行。如果我用 pub fn add<'de, T: serde::Deserialize<'de>>(&mut self) { 来尝试,我会遇到生命周期问题:

cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
expected `serde::Deserialize<'_>`
   found `serde::Deserialize<'de>`

编译错误告诉你如何修复错误,只需添加一个Deserialize绑定到泛型参数T。由于借用来自 &self.samples,因此 Deserialize 也必须以某种方式绑定到 self,我们可以使用通用参数 'a:

指定
use serde::de::Deserialize;
use serde_reflection::{Registry, Samples, Tracer, TracerConfig};

pub struct MessageRegistry {
    tracer: Option<Tracer>,
    samples: Samples,
    registry: Option<Registry>,
}

impl MessageRegistry {
    pub fn new() -> MessageRegistry {
        MessageRegistry {
            tracer: Some(Tracer::new(TracerConfig::default())),
            samples: Samples::new(),
            registry: None,
        }
    }

    pub fn add_type<'a, T: Deserialize<'a>>(&'a mut self) {
        self.tracer.as_mut().unwrap().trace_type::<T>(&self.samples).unwrap();
    }

    pub fn to_json_string(&mut self) -> String {
        self.registry = self.tracer.take().unwrap().registry().ok();
        serde_json::to_string(self.registry.as_ref().unwrap()).unwrap()
    }
}

注意:tracer.registry() 消耗了 tracer,因此我不得不将其包装在 Option 中。还添加了一个包裹在对象中的 Registry 字段,表示消费的结果 tracer.