Rocket cannot parse JSON - rust

I'm having an error when trying to parse JSON with rocket. This is my code:
extern crate serde;
use rocket::serde::{json::Json, Deserialize};
use serde::Serialize;
#[macro_use]
extern crate rocket;
mod eth;
mod rocket_test;
#[launch]
fn rocket() -> _ {
rocket::build().mount("/task", routes![body])
}
#[derive(Serialize, Deserialize)]
struct Message2 {
id: usize,
}
#[post("/", format = "json", data = "<message>")]
async fn body(message: Json<Message2>) -> &'static str {
"Fine"
}
And this is my toml file:
[dependencies]
serde = {version = "1.0", features = ["derive"]}
serde_derive = "1.0"
serde_json = "1.0"
tester = "0.9.0"
tokio = {version = "1", features = ["full"]}
[dependencies.rocket]
features = ["json"]
version = "0.5.0-rc.1"
I'm getting this error
thread 'rocket-worker-thread' panicked at 'assertion failed: `(left == right)`
left: `0x28f12470657`,
right: `0x28f12470640`', C:\Users\gadum\.cargo\registry\src\github.com-1ecc6299db9ec823\tokio-1.16.0\src\io\util\take.rs:93:9
note: run with `RUST_BACKTRACE=1` environment variable
to display a backtrace
>> Handler body panicked.
It's just the same as in the example of JSON parsing. But I have no idea what is going wrong.
I'm sending requests with VSCode Rest client just like this
POST http://127.0.0.1:8000/task
content-type: application/json
{
"id": 10
}

It looks like version 1.16.0 of tokio has an error: https://github.com/tokio-rs/tokio/issues/4435
Do a cargo update and it should update your dependency to 1.16.1.

Related

Retrieve the version of a dependency in build.rs script

I would like to expose in my REPL (built on top of Boa) the version of the js engine:
I'm trying to use a build.rs file for that:
use std::env;
fn main() {
println!("cargo:rustc-env=BOA_VERSION={}", "0.16.0");
}
And somewhere in my main.rs:
context.register_global_property("BOA_VERSION", env!("BOA_VERSION"), Attribute::all());
Obviously I have hardcoded the version of the crate but wondering if there is a programmatically way to get the version.
If all you need is to get access to the version information in your code, you can skip making a build.rs file for it. Instead, we can use the serde and toml crates to parse your Cargo.toml file directly. Below is a sample of how that might look.
Cargo.toml:
[package]
name = "dependency-information"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
serde = { version = "1.0.152", features = ["derive"] }
toml = "0.7.0"
main.rs:
use std::collections::HashMap;
use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize, Deserialize)]
#[serde(untagged)]
enum DependencyValue {
String(String),
Object {
version: String,
features: Vec<String>,
},
}
#[derive(Debug, Serialize, Deserialize)]
struct CargoToml {
dependencies: HashMap<String, DependencyValue>,
}
fn main() {
let cargo_toml_raw = include_str!("../Cargo.toml");
let cargo_toml: CargoToml = toml::from_str(cargo_toml_raw).unwrap();
println!("{cargo_toml:#?}");
}
And if we run it, we get this output:
CargoToml {
dependencies: {
"toml": String(
"0.7.0",
),
"serde": Object {
version: "1.0.152",
features: [
"derive",
],
},
},
}
Note that you probably would want to include the Cargo.toml file dynamically instead of using include_str!. I used include_str! for the sake of the example.

Issue trying to set up Rocket server with a Mongodb pool

I'm switching from Nodejs with NestJs to Rust Rocket + juniper. Even if I start feeling confident in Rust i'm having difficulties with some simple thing.
I'm trying to create a mongdb pool to attach to my app but I'm having some issue. Here is my main function:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[macro_use] extern crate rocket_contrib;
#[rocket_contrib::database("db")]
struct DatabaseConnection(rocket_contrib::databases::mongodb::db::Database);
// mod features;
#[rocket::main]
async fn main() {
rocket::build()
.attach(DatabaseConnection::fairing())
.mount(
"/",
rocket::routes![],
)
.launch()
.await
.expect("server to launch");
}
And here is my cargo.toml file:
[package]
name = "rocket_graphql"
version = "0.1.0"
edition = "2018"
[dependencies]
rocket = "0.5.0-rc.1"
juniper = { git = "https://github.com/graphql-rust/juniper" }
juniper_rocket = "0.2.0"
mongodb = "2.0.0-beta.2"
bson = "1.2.1"
tokio = { version = "1.8.0", features = ["full"] }
[dependencies.rocket_contrib]
version = "0.4.10"
default-features = false
features = ["mongodb_pool"]
[global.databases]
db = {url = "my-mongo-atlas-instance-url"}
I'm getting an error on this line #[rocket_contrib::database("db")]
it says: unresolved import 'rocket' no 'Outcome' in the root.
Can you please tell me what I'm doing wrong here?
Thank you very much
I'm using Rocket 0.5. According to the changelog, the rocket_contrib has been deprecated in favor for rocket_sync_db_pools which doesn't seem to cover mongodb yet. So what I did is to create a state struct to hold a reference to the database. So thanks to the manage method on rocket, the reference to the database can be passed to all the routes. Feel free to correct it if I did anything wrong
I ended up doing this:
#![feature(proc_macro_hygiene, decl_macro)]
use mongodb::{
Client, Database,
};
use rocket::{self, get, State};
#[get("/")]
async fn index(mongo_db: &State<AppDataPool>) -> &'static str {
for coll_name in mongo_db.mongo.list_collection_names(None).await {
println!("collection: {:?}", coll_name);
}
"helloooo"
}
struct AppDataPool {
mongo: Database,
}
#[rocket::main]
async fn main() {
let client = Client::with_uri_str("----").await;
let db = client.unwrap().database("my-db");
for coll_name in db.list_collection_names(None).await {
println!("collection: {:?}", coll_name);
}
rocket::build()
.manage(AppDataPool { mongo: db })
.mount("/", rocket::routes![index])
.launch()
.await
.expect("server to launch");
}

Rust trait not satisfied

I'm new to rust and tried searching in stackoverflow as well as reading the serde documentation
https://docs.serde.rs/serde/trait.Serialize.html and https://serde.rs/impl-serialize.html, but I was a bit lost.
I would like to use Tera to generate html and the struct I'm passing it does not have the trait serde::ser::Serialize implemented and I tried to implement it but it doesn't appear quite right.
Cargo.toml dependencies
serde = "1.0.115"
serde_derive = "1.0.115"
serde-xml-rs = "0.4.0"
tera = "0.7.2"
main.rs
extern crate tera;
#[macro_use]
extern crate serde_derive;
extern crate serde;
use tera::Context;
use serde::ser::{Serialize, SerializeStruct, Serializer};
#[derive(Serialize, Debug)]
struct Person {
firstname: String,
lastname: String,
age: i32,
}
#[derive(Debug)]
struct Attendees {
people: Vec<Person>,
updatedOn: String,
updatedBy: String,
}
impl Serialize for Attendees {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let mut s = serializer.serialize_struct("Person", 3)?;
s.serialize_field("people", &self.people)?;
s.serialize_field("updatedOn", &self.updatedOn)?;
s.serialize_field("updatedBy", &self.updatedBy)?;
s.end()
}
}
fn main() {
let mut context = Context::new();
let mut peeps: Vec<Person> = Vec::new();
let mut attendees = Attendees {
people: peeps,
updatedOn: String::from("today"),
updatedBy: String::from("someone"),
};
context.add("attendees", &attendees);
}
compiler says:
mytest % cargo run
Compiling mytest v0.1.0 (/home/mike/mytest)
error[E0277]: the trait bound `Attendees: serde::ser::Serialize` is not satisfied
--> src/main.rs:44:29
|
44 | context.add("attendees", &attendees);
| ^^^^^^^^^^ the trait `serde::ser::Serialize` is not implemented for `Attendees`
error: aborting due to previous error
I am clearly missing something... Can anyone please help?
The trait you implemented and the trait that the error is referring are not the same, because they refer to two different versions of serde.
[[package]]
name = "tera"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c37e2aaa53871f9c3722a20f8951fea0afd366955e11542a58feb71997c6d769"
dependencies = [
"chrono",
"error-chain",
"glob",
"humansize",
"lazy_static 0.2.11",
"pest",
"regex",
"serde 0.9.15",
"serde_json",
"slug",
"url",
]
tera 0.7.2 is not using the version 1.0.* of serde, but 0.9.*.
You may use a more recent of tera, or use a compatible serde version in your Cargo.toml:
[dependencies]
serde = "0.9.15"
serde_derive = "0.9.15"

How to forward data from a reqwest::blocking::Body in a Rocket responder?

I'm able to request a PNG file with reqwest which I can save to a file through copy().
I'd like to forward the image as a Rocket response. I don't know how to pass the response contents there.
I tried to use Content(ContentType::PNG, response) but I can't figure out how to match a type that has implemented rocket::response::Responder trait. Rocket can't use the Bytes type returned by response.bytes().
#![feature(proc_macro_hygiene, decl_macro)]
extern crate reqwest;
#[macro_use]
extern crate rocket;
use anyhow::Result;
use reqwest::header::USER_AGENT;
use reqwest::Response;
use rocket::http::ContentType;
use rocket::response::content::Content;
#[get("/")]
fn myroute() -> Result<Content<String>, anyhow::Error> {
let client = reqwest::blocking::Client::new();
let response = client.get("https://www.rust-lang.org/static/images/rust-logo-blk.svg")
.header(USER_AGENT, "rust-reqwest")
.send()?;
Ok(Content(ContentType::PNG, response.bytes()))
}
fn rocket() -> rocket::Rocket {
rocket::ignite()
.mount("/", routes![myroute])
}
fn main() {
rocket().launch();
}
[dependencies]
anyhow = "1.0"
rocket = "0.4.2"
reqwest = { version = "0.10.4", features = ["blocking", "json"] }

Project with serde cannot compile

When I try to run the example from the serde repository:
#![feature(proc_macro)]
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
I get an error:
error: failed to run rustc to learn about target-specific
information
Caused by: process didn't exit successfully: rustc - --crate-name _
--print=file-names --crate-type bin --crate-type proc-macro --crate-type rlib --target x86_64-unknown-linux-gnu (exit code: 101)
--- stderr error: unknown crate type: proc-macro
My Rust version is 1.13.0 and my Cargo.toml has these dependencies:
[dependencies]
serde = "*"
serde_derive = "*"
Should I use other dependencies or extra configuration?
The #![feature(...)] attribute indicates code that uses Rust features which have not been stabilized yet. At the time the question was asked, the proc_macro feature was not yet stable. Serde needs this feature for its #[derive(Serialize, Deserialize)] macros.
Custom derives have been stabilized as of Rust 1.15 so the code in the question (with the feature attribute removed) should work on any Rust compiler since that version.

Resources