Skip to content

Instantly share code, notes, and snippets.

@rofrol
Last active January 17, 2022 16:20
Show Gist options
  • Save rofrol/d86b59adcbca51f95fbf8847f5a039e0 to your computer and use it in GitHub Desktop.
Save rofrol/d86b59adcbca51f95fbf8847f5a039e0 to your computer and use it in GitHub Desktop.
Rust + Rocket + rust-postgres
[package]
name = "hello-rocket"
version = "0.1.0"
authors = ["Roman Frołow"]
[dependencies]
rocket = "0.2.0"
rocket_codegen = "0.2.0"
postgres = "0.14"
serde = "0.9"
serde_json = "0.9"
serde_derive = "0.9"
rocket_contrib = "0.2.4"
#![feature(plugin)]
#![plugin(rocket_codegen)]
extern crate rocket;
extern crate postgres;
extern crate serde_json;
#[macro_use]
extern crate rocket_contrib;
#[macro_use]
extern crate serde_derive;
use postgres::{Connection, TlsMode};
use rocket_contrib::{JSON, Value};
#[get("/")]
fn index() -> &'static str {
"Hello, world!"
}
#[get("/<name>")]
fn name(name: &str) -> String {
format!("Hello, {}!", name)
}
#[derive(Serialize, Deserialize)]
struct UserInformation {
userId: i32,
name: String,
surname: String,
magicUrl: String,
notifications: Vec<Notification>,
}
#[derive(Serialize, Deserialize)]
struct Notification {
context: String,
status: bool,
}
#[get("/userInformation")]
fn user_information() -> JSON<UserInformation> {
let user_id = 1;
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None)
.unwrap();
let rows = &conn.query(
"SELECT \"userId\", name, surname, \"magicUrl\" FROM user_information where \"userId\" = $1",
&[&user_id])
.unwrap();
let row = rows.into_iter().next().unwrap();
let mut notifications = Vec::new();
for row in &conn.query(
"select context, status from user_information as u join notifications as n on n.\"userId\" \
= u.\"userId\" and u.\"userId\" = $1",
&[&user_id])
.unwrap() {
let notification = Notification {
context: row.get(0),
status: row.get(1),
};
notifications.push(notification);
}
JSON(UserInformation {
userId: row.get(0),
name: row.get(1),
surname: row.get(2),
magicUrl: row.get(3),
notifications: notifications,
})
}
#[derive(Serialize, Deserialize)]
struct DataSet {
id: i32,
name: String,
}
// create table data_sets (
// name varchar,
// owner varchar,
// "ownerEmail" varchar,
// "releaseDate" varchar,
// "updatedDate" varchar,
// rating float,
// favourite bool,
// description varchar,
// usage varchar,
// "categoryId" integer,
// private bool,
// url varchar,
// id serial primary key
// );
#[get("/dataSets")]
fn data_sets() -> JSON<Vec<DataSet>> {
let mut vec = Vec::new();
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None)
.unwrap();
for row in &conn.query("SELECT id, name FROM data_sets", &[])
.unwrap() {
let data_set = DataSet {
id: row.get(0),
name: row.get(1),
};
// note: move occurs because `data_set` has type `DataSet`,
// which does not implement the `Copy` trait
println!("Found DataSet {}", &data_set.name);
vec.push(data_set);
}
JSON(vec)
}
#[derive(Serialize, Deserialize)]
struct DataSetWithComments {
id: i32,
name: String,
comments: Vec<Comment>,
}
#[derive(Serialize, Deserialize)]
struct Comment {
id: i32,
content: String,
userName: String,
userPhotoUrl: String,
date: String,
}
#[get("/dataSets/<url>")]
fn data_set(url: &str) -> JSON<DataSetWithComments> {
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None)
.unwrap();
let url2 = "dataSets/".to_owned() + url;
let rows = &conn.query("SELECT id, name FROM data_sets where url = $1", &[&url2])
.unwrap();
let row = rows.into_iter().next().unwrap();
let data_set_id: i32 = row.get(0);
let mut comments = Vec::new();
for row in
&conn.query("select c.id, content, \"userName\", \"userPhotoUrl\", date from comments as c \
join data_sets as d on c.data_set_id = d.id and d.id = $1",
&[&data_set_id])
.unwrap() {
let comment = Comment {
id: row.get(0),
content: row.get(1),
userName: row.get(2),
userPhotoUrl: row.get(3),
date: row.get(4),
};
comments.push(comment);
}
JSON(DataSetWithComments {
id: row.get(0),
name: row.get(1),
comments: comments,
})
}
#[derive(Serialize, Deserialize)]
struct Category {
id: i32,
title: String,
route: String,
count: i32,
contentUrl: String,
}
#[derive(Serialize, Deserialize)]
struct DataSetShort {
id: i32,
name: String,
description: String,
owner: String,
releaseDate: String,
rating: f32,
favourite: bool,
url: String,
}
#[get("/dataSetsCategories/<url>")]
fn data_set_category(url: &str) -> JSON<DataSetShort> {
let conn = Connection::connect("postgres://postgres:p@localhost/algo2go", TlsMode::None)
.unwrap();
let url2 = "dataSetsCategories/".to_owned() + url;
let rows = &conn.query("select id from data_sets_categories where \"contentUrl\" = $1",
&[&url2])
.unwrap();
let row = rows.into_iter().next().unwrap();
let data_set_category_id: i32 = row.get(0);
let mut dataSetShortRows = &conn.query("select d.id, name, SUBSTRING(description,0,100) as description, owner, \"releaseDate\", \
rating, favourite, url from data_sets d join data_sets_in_categories di on d.id = di.data_sets_id \
and di.data_sets_categories_id = $1",
&[&data_set_category_id])
.unwrap();
let dataSetShortRow = dataSetShortRows.into_iter().next().unwrap();
JSON(DataSetShort {
id: dataSetShortRow.get(0),
name: dataSetShortRow.get(1),
description: dataSetShortRow.get(2),
owner: dataSetShortRow.get(3),
releaseDate: dataSetShortRow.get(4),
rating: dataSetShortRow.get(5),
favourite: dataSetShortRow.get(6),
url: dataSetShortRow.get(7),
})
}
#[error(404)]
fn not_found() -> JSON<Value> {
JSON(json!({
"status": "error",
"reason": "Resource was not found."
}))
}
fn main() {
rocket::ignite()
.mount("/", routes![index])
.mount("/hello", routes![name])
.mount("/api",
routes![user_information, data_sets, data_set, data_set_category])
.catch(errors![not_found])
.launch();
}
write_mode = "overwrite"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment