Rust Rocket REST API - rust

I can not compile main.rs file. And in probabilityofunitinjectorfail I want to add random generated number 0-100.
error: cannot find function 'iginite' in create 'rocket'.
Here is main.rs:
#![feature(decl_macro)]
#[macro_use] extern crate rocket;
#[get("/probabilityOfUnitInjectorFail")]
fn probabilityofunitinjectorfail() -> &'static str {
"/probabilityOfUnitInjectorFail"
}
fn main() {
rocket::ignite()
.mount("/", routes![probabilityofunitinjectorfail])
.launch();
}

#![feature(decl_macro)]
#[macro_use] extern crate rocket;
#[get("/probabilityOfUnitInjectorFail")]
fn probabilityofunitinjectorfail() -> &'static str{
"/probabilityOfUnitInjectorFail"
}
#[launch]
fn rocket() -> _ {
rocket::build().mount("/", routes![probabilityofunitinjectorfail])
}
In new version ignite() was changed to build()

Related

Diesel and Rocket imports break as soon as I include a file

I have the file "user.rs" that has the struct of a postgres database table. Whenever I try to include it in my main.rs file (A Rocket web project), all of the Diesel "stuff" can't resolve. Here is my user.js file:
use super::schema::users;
pub mod handler;
pub mod repository;
pub mod router;
#[derive(Queryable, AsChangeset, Serialize, Deserialize)]
#[table_name = "users"]
pub struct User {
pub id: String,
pub username: String,
pub password: String,
}
#[derive(Insertable)]
#[table_name = "users"]
pub struct InsertableUser {
username: String,
password: String,
}
pub impl InsertableUser {
pub fn from_user(user: User) -> InsertableUser {
InsertableUser {
username: user.username,
password: user.password,
}
}
}
pub fn all(connection: &PgConnection) -> QueryResult<Vec<User>> {
users::table.load::<User>(&*connection)
}
pub fn get(id: i32, connection: &PgConnection) -> QueryResult<User> {
users::table.find(id).get_result::<User>(connection)
}
pub fn insert(user: User, connection: &PgConnection) -> QueryResult<User> {
diesel::insert_into(users::table)
.values(&InsertableUser::from_user(user))
.get_result(connection)
}
pub fn update(id: i32, user: User, connection: &PgConnection) -> QueryResult<User> {
diesel::update(users::table.find(id))
.set(&user)
.get_result(connection)
}
pub fn delete(id: i32, connection: &PgConnection) -> QueryResult<usize> {
diesel::delete(users::table.find(id)).execute(connection)
}
And here is my main.rs:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_contrib;
use rocket_contrib::databases::diesel;
#[database("camera-server-db")]
struct CameraServerDbConn(diesel::PgConnection);
mod user;
#[get("/")]
fn index() -> &'static str {
"Hello World!"
}
fn main() {
rocket::ignite()
.attach(CameraServerDbConn::fairing())
.mount("/", routes![index])
.launch();
}
If I remove mod user; from main.rs, no error show up. When I run cargo check, I get many "cannot find x in this scope". Here's an example:
error: cannot find derive macro `AsChangeset` in this scope
--> src/user.rs:7:21
|
7 | #[derive(Queryable, AsChangeset, Serialize, Deserialize)]
| ^^^^^^^^^^^
I'm trying to follow this guide (which is admittedly quite out of date, but it was one of the only actual guides I could find).
As mentioned in the linked guide in the section "The last step", you need to import diesel correctly otherwise the compiler cannot resolve those traits/derives/functions. That means you need to change your main.rs file as following:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
#[macro_use]
extern crate rocket_contrib;
#[macro_use]
extern crate diesel;
use rocket_contrib::databases::diesel;
#[database("camera-server-db")]
struct CameraServerDbConn(diesel::PgConnection);
mod user;
#[get("/")]
fn index() -> &'static str {
"Hello World!"
}
fn main() {
rocket::ignite()
.attach(CameraServerDbConn::fairing())
.mount("/", routes![index])
.launch();
}
(note the additional #[macro_use] extern crate diesel; in your extern crate section.)

I can not deserialize json String to struct with serde

I have trouble deserializing json to struct.
Here is code that simulates my problem:
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender };
extern crate serde_json;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize, Debug)]
struct Foo<'a> {
a: u32,
b: u32,
c: &'a str,
}
fn main() {
let (msg_tx, msg_rx): (Sender<Foo>, Receiver<Foo>) = mpsc::channel();
{
let js = r#"{"a":33, "b":44, "c": "ss"}"#; // initially I have a json String, here I simulate a problem
let js_string = String::from(js);
let f = test(js_string.as_str());
msg_tx.send(f);
}
}
fn test(js: &str) -> Foo {
let foo: Foo = serde_json::from_str(js).unwrap();
foo
}
Running that code results to the error 'js' does not live long enough.
I know that changing the type of Foo c field to String will resolve the problem, but I would like to know if there is a another solution.
The reason for this error is the way serde crate works in that situation, - it uses inside returned foo variable a reference to original variable, which is js_string, so it goes out of scope just after calling msg_tx.send(f); but f has a reference to it and lives longer than that scope.
I'm still a rust beginner and want to master lifetime concept. I tried to fix my problem with function wrapper to set right lifetime, but failed.
You have to ensure that js_string lives longer than the channel, to ensure this you can create a scope for "working" with the channel:
use std::sync::mpsc;
use std::sync::mpsc::{Receiver, Sender };
extern crate serde_json;
extern crate serde;
#[macro_use]
extern crate serde_derive;
#[derive(Deserialize, Debug)]
struct Foo<'a> {
a: u32,
b: u32,
c: &'a str,
}
fn main() {
let js = r#"{"a":33, "b":44, "c": "ss"}"#;
let js_string = String::from(js);
let f = test(js_string.as_str());
{
let (msg_tx, msg_rx): (Sender<Foo>, Receiver<Foo>) = mpsc::channel();
msg_tx.send(f);
} // channel is dropped here and js_string is no longer borrowed
} // js_string is dropped here
fn test(js: &str) -> Foo {
let foo: Foo = serde_json::from_str(js).unwrap();
foo
}

I get a "no 'Json' in root" error when building a rust rocket api

So I was trying to follow the example from https://medium.com/sean3z/building-a-restful-crud-api-with-rust-1867308352d8 to build a simple REST API. Half way through, the rust compiler gives me the the following error:
unresolved imports 'rocket_contrib::Json', 'rocket_contrib::Value' no 'Json' in the root
I can't seem to figure out what I am doing wrong.
Here is my Cargo.toml:
[package]
name = "rust-api-test"
version = "0.1.0"
authors = ["username"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rocket = "0.4.4"
serde = "1.0"
serde_json = "1.0"
serde_derive = "1.0"
[dependencies.rocket_contrib]
version = "0.4.4"
default-features = false
features = ["json"]
hero.rs:
#[derive(Serialize, Deserialize)]
pub struct Hero {
pub id: Option<i32>,
pub name: String,
pub identity: String,
pub hometown: String,
pub age: i32
}
and main.rs:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate serde_derive;
mod hero;
use hero::{Hero};
use rocket_contrib::{Json, Value};
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
fn main() {
rocket::ignite().mount("/", routes![index]).launch();
}
I get the error on line 10:
use rocket_contrib::{Json, Value};
I followed Sven Marnach's advice and now it works. I changed my main.rs file to the following:
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[macro_use] extern crate rocket_contrib;
#[macro_use] extern crate serde_derive;
mod hero;
use hero::{Hero};
use rocket_contrib::json::{Json, JsonValue};
#[post("/", data = "<hero>")]
fn create(hero: Json<Hero>) -> Json<Hero> {
hero
}
#[get("/")]
fn read() -> JsonValue {
json!([
"hero 1",
"hero 2"
])
}
#[put("/<id>", data = "<hero>")]
fn update(id: i32, hero: Json<Hero>) -> Json<Hero> {
hero
}
#[delete("/<id>")]
fn delete(id: i32) -> JsonValue {
json!({"status": "ok"})
}
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
fn main() {
rocket::ignite()
.mount("/", routes![index])
.mount("/hero", routes![create, update, delete])
.mount("/heroes", routes![read])
.launch();
}
The example code was written for the now obsolete version 0.3.x of Rocket. You can't start new projects based on the old version anymore, since some of the dependencies have been yanked from crates.io. However, it's relatively easy to fix the example code – the import the compiler is complaining about isn't used anyway, so you can simply remove it. In version 0.4.x of rocket_contrib the rocket_contrib::Json struct has been moved to rocket_contrib::json::Json, so you can also import from the new location if you need it. The rocket_contrib::Value enum has been replaced with rocket_contrib::json::JsonValue, albeit with a different implementation, so you may need to adapt any uses to the new interface.

How do I use the annotation and micro in the mod of the test scope?

The structure of my code as below.
I ran 'cargo run' and it works. But when I ran 'cargo test', I got the errors as below. Could you please tell me why and how can I fix them?
error: cannot find attribute get in this scope
error: cannot find macro routes in this scope
src/main.rs
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
mod common;
fn main() {
common::run();
}
src/common.rs
#[get("/hello")]
pub fn hello() -> &'static str {
"hello"
}
pub fn run() {
rocket::ignite().mount("/", routes![hello]).launch();
}
tests/development.rs
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use]
extern crate rocket;
#[cfg(test)]
mod common;
#[test]
fn test_development_config() {
common::run();
}
tests/common.rs
use rocket::http::Status;
use rocket::local::Client;
#[get("/check_config")]
fn check_config() -> &'static str {
"hello"
}
pub fn run() {
let rocket = rocket::ignite().mount("/", routes![check_config]);
let client = Client::new(rocket).unwrap();
let response = client.get("/hello").dispatch();
assert_eq!(response.status(), Status::Ok);
}
Each .rs file in the tests/ folder is separately compiled and executed as a test. So development.rs is compiled, "includes" common.rs and it works. But then common.rs is compiled individually and it fails because there is no #[macro_use] extern crate rocket; anywhere.
One solution would be to put your common.rs into tests/common/mod.rs. Files in sub-directories of tests are not automatically compiled as test.

I want to start Rocket in a module out of `main()` but failed

I want to start Rocket in a module out of main(), thus can simplify main() but I failed. I modified the Quicktart from rocket
The code:
mod myRocket {
#![feature(plugin)]
#![plugin(rocket_codegen)]
extern crate rocket;
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
pub fn startup() {
rocket::ignite().mount("/", routes![index]).launch();
}
}
fn main() {
myRocket::startup();
}
The error:
error: cannot find macro `routes!` in this scope
--> src\main.rs:12:37
|
12 | rocket::ignite().mount("/", routes![index]).launch();
|
I don't know how to fix it.
I achieved. My project's crate is rocket_demo
main.rs
extern crate rocket_demo;
use rocket_demo::my_rocket;
fn main() {
my_rocket::startup();
}
lib.rs
#![feature(plugin)]
#![plugin(rocket_codegen)]
extern crate rocket;
pub mod my_rocket;
The first three lines can't be in my_rocket/mod.rs, otherwise routes! will not find!
my_rocket/mod.rs
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
pub fn startup() {
::rocket::ignite().mount("/", routes![index]).launch();
}

Resources