Parsing JSON into a struct and returning the resulting struct

Hey everyone. I'm completely new to rust and came from Javascript.

I'm trying to write an abstracted wrapper for Telegram's TDLib C JSON interface and I'm having trouble with the conversion of JSON data into structs.

Here is the struct setup I'm using to mirror the expected JSON outputs from the C program.

trait Update<T: OptionValue> {}

#[derive(Serialize, Deserialize)]
struct UpdateOption<T: OptionValue> {
  @type: String,
  name: String,
  value: T,
}

impl<T: OptionValue> Update<T> for UpdateOption<T> {}

trait OptionValue {}

#[derive(Serialize, Deserialize)]
struct OptionValueString {
  @type: String,
  value: String,
}

impl OptionValue for OptionValueString {}

self.tdlib.receive returns a String of JSON. For example,
{"@type":"updateOption","name":"version",value:{"@type":"OptionValueString","value":"1.6.0"}}

Ideally the following function would be able to create a struct from the JSON data but I'm unable to get around the issue that response goes out of scope immediately and therefore I can't return the struct parsed by serde_json::from_str

pub fn receive<'de, T: Deserialize<'de>>(&self) -> Result<T, tdjson::NoResponseError> {
  match self.tdlib.receive(TIMEOUT) {
    Ok(response) => Ok(serde_json::from_str(&response).unwrap()),
    Err(_) => Err(tdjson::NoResponseError),
  }
}

Is there any other way of doing this or am I missing something fundamental?

Try using serde::de::DeserializeOwned instead of Deserialize<'de> as the trait bound. The current function implies that the resulting T uses data from the response, which can be useful to avoid unnecessary copying in some situations. In this case that's probably not what you want, by using DeserializeOwned you can indicate that the deserialized T should not contain references to the original response. You can read more about Deserialize and DeserializeOwned at https://serde.rs/lifetimes.html

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.