7

I'm trying to make a webserver that accepts some parameters as JSON, and turns them into a struct which I'll then store somewhere else in my app.

I have this data struct in a file called status.rs:

use serde::{Serialize, Deserialize}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Status { pub id: String, pub rssi: Option<i8>, pub carrier: Option<String>, pub timestamp: u64, } 

I am then using the following code inside a service in Hyper to try to parse the body of the request and turn it into my struct. The only difference is that I want to add the timestamp field according to the timestamp on the server, not on the client:

let timestamp: u64 = SystemTime::now() .duration_since(UNIX_EPOCH) .expect("PANIC! Time is running backwards!") .as_secs(); Box::new(req.into_body().concat2().map(|body| { let body_bytes = body.into_bytes(); let body_str = match str::from_utf8(&body_bytes) { Ok(v) => v, Err(e) => { // TODO: this is shitty error handling panic!("Unable to read UTF8 input: {}", e); } }; let input_data: Value = serde_json::from_str(body_str).unwrap(); let data = Status { id: input_data.get("id").unwrap(), timestamp: timestamp, rssi: input_data.get("rssi"), carrier: input_data.get("carrier"), }; update(data); })); 

The update function just inserts it into a data storage structure.

I have tried doing this in several different ways, but this way gives me the problem that each one of these fields is of type Option<&Value> (I think).

Hopefully the outcome I'm trying to achieve is clear enough, I just have no idea how to take the request body, parse the JSON, add in a timestamp, and package it up in a struct which I then store in my database.

How should I go about this?

4
  • what is the problem ? Commented Feb 16, 2019 at 18:53
  • That I want to parse JSON from the request body, add a field, and then parse it into a Status struct, and I'm not quite sure how to go about it. Commented Feb 17, 2019 at 23:41
  • Did you ever figure it out? Commented May 9, 2019 at 4:32
  • @JustinThomas: I didn't not :( Commented May 23, 2019 at 17:29

1 Answer 1

6

You're trying to convert body to byte slice, then to string, then to serde_json::Value, then to Status. Quite a lot of unnecessary intermediate steps, right? Just read the docs:

let body = req.into_body().concat2().wait().unwrap().into_bytes(); let s: Status = serde_json::from_slice(&body).unwrap(); 
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, that is definitely better but I’m still not sure how to go about adding this extra timestamp field which is not an Option (because a Status isn’t valid without one) since it isn’t included in the request body.
calling wait blocks indefinitely for me since it's in the hyper request handler.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.