3

I am trying to output the Hyper HTTP Request Object as JSON. I am using Serde to Serialize the object to JSON.

Since I am not defining the HTTP Request Struct, I can't add the attribute #[derive(Serialize, Deserialize)] to it. any ideas on how to get around this?

my code:

use hyper::body::HttpBody as _;    
use hyper::{Body, Client, Method, Request, Uri};    
use hyper_tls::HttpsConnector;    
#[cfg(feature = "std")]
use serde::{Deserialize, Deserializer, Serialize, Serializer};    
use serde_json::{json, Result as re_, Value};    
use tokio::io::{stdout, AsyncWriteExt as _};    
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let https = HttpsConnector::new();

// Client Object
let client = Client::builder().build::<_, hyper::Body>(https);    
let uri: Uri = "https://api.api.com".parse()?;
let http_body = String::from(" body");
let content_length = http_body.chars().count();
//Build Request
let req = Request::builder()
    .method(Method::POST)
    .uri(uri)
    .header("accept", "application/xml")
    .header("content-type", "application/xml")
    .header("Content-Length", content_length)
    .body(Body::from(http_body))?;

// Serialize it to a JSON string.
let j = serde_json::to_string(&req)?;

// Print HTTP Request
println!("{}", j);

// Await the response...
let mut resp = client.request(req).await?;
println!("Response: {}", resp.status());
Ok(())
}

stack trace shows:

|     let j = serde_json::to_string(&req)?;
     |             --------------------- ^^^^ the trait `serde::ser::Serialize` is not implemented for `Request<Body>`
     |             |
     |             required by a bound introduced by this call
     |
note: required by a bound in `serde_json::to_string`
    --> /home/joel/.cargo/registry/src/github.com-1ecc6299db9ec823/serde_json-1.0.79/src/ser.rs:2225:17
     |
2225 |     T: ?Sized + Serialize,
     |                 ^^^^^^^^^ required by this bound in `serde_json::to_string`

Cargo.toml

[dependencies]
serde = { version = "1.0.136", features = ["derive"] }
serde_json = "1.0.79"
serde_derive = "1.0.136"
hyper = { version = "0.14.18", features = ["full"] }
tokio = { version = "1.17.0", features = ["full"] }
hyper-tls = "0.5.0"
rustls = "0.20.4"
Herohtar
  • 5,347
  • 4
  • 31
  • 41
JOW
  • 244
  • 4
  • 18

1 Answers1

1

If you want to derive de/serialize for an external crate you can follow the oficial serde guide for doing so.

Also, if you are trying to serialize it just to print it, maybe you could consider writing or using a default Debug or Display implementation over a wrapper. The default Debug one may do:

// Print HTTP Request
println!("{req:?}");
Netwave
  • 40,134
  • 6
  • 50
  • 93
  • no, I tried and compiler throws error at line 33. it expects struct 'Request' and not 'Request. Also this seems to be unrelated to my question. – JOW Apr 17 '22 at 19:10
  • @JOW yeah, it is not a solution though. But I dont think it is unrelated. If you wanted just a way of bypass serde for external crates then you should have asked about that specificallly instead with a minimal example. – Netwave Apr 17 '22 at 20:08
  • after the last Edit, this answer was helpful! – JOW May 08 '22 at 17:04