-1

I'm trying to use serde-reflection to create a JSON structure explaining the struct structure in order to transfer and receive structs as JavaScript an ArrayBuffer and then de-serialize that into a JavaScript Object in the browser.

I want a way to "register" the structs I'm interested in and then keeping track of all those registered types so that they can be returned from a web server.

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()
    }
}

I'm stuck on using the tracer.trace_type::<T>(&self.samples) line. If I try it out with pub fn add<'de, T: serde::Deserialize<'de>>(&mut self) { instead I get into problems with the lifetime instead:

cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
expected `serde::Deserialize<'_>`
   found `serde::Deserialize<'de>`
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
tirithen
  • 3,219
  • 11
  • 41
  • 65

1 Answers1

1

The compile error tells you how to fix the error, just add a Deserialize bound to the generic parameter T. Since the borrow comes from &self.samples then Deserialize must also be tied to self somehow, which we can specify with the generic parameter '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()
    }
}

Note: tracer.registry() consumes the tracer so I had to wrap it in an Option. Also added a Registry field wrapped in the object that represents the results of the consumed tracer.

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98