first experiments with rocket

session-crate
Ondřej Hruška 4 years ago
commit a1b8f5a1a1
Signed by: MightyPork
GPG Key ID: 2C5FD5035250423D
  1. 4
      .gitignore
  2. 6
      .idea/$CACHE_FILE$
  3. 2
      .idea/.gitignore
  4. 1289
      Cargo.lock
  5. 26
      Cargo.toml
  6. 2
      Rocket.toml
  7. 39
      src/main.rs
  8. 52
      src/store/mod.rs
  9. 16
      templates/index.html.tera

4
.gitignore vendored

@ -0,0 +1,4 @@
/target
**/*.rs.bk
.idea/
inventory.json

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NodePackageJsonFileManager">
<packageJsonPaths />
</component>
</project>

2
.idea/.gitignore vendored

@ -0,0 +1,2 @@
# Default ignored files
/workspace.xml

1289
Cargo.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,26 @@
[package]
name = "rocket-inv"
version = "0.1.0"
authors = ["Ondřej Hruška <ondra@ondrovo.com>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rocket-download-response = "0.4.9"
#rocket-include-tera = "0.4.5"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
json_dotpath = "0.1.2"
parking_lot = "0.10.0"
[dependencies.rocket]
version = "0.4.2"
default-features = false
[dependencies.rocket_contrib]
version = "0.4.2"
default-features = false
features = ["json", "serve", "tera_templates"]

@ -0,0 +1,2 @@
[global]
port = 8123

@ -0,0 +1,39 @@
#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
#[macro_use] extern crate serde;
//use rocket::request::FromSegments;
//use rocket::http::uri::Segments;
//use rocket_contrib::serve::StaticFiles;
use rocket_contrib::templates::Template;
mod store;
use crate::store::Store;
use rocket::State;
use parking_lot::RwLock;
use rocket::response::Redirect;
use rocket::http::Status;
use rocket::request::Form;
use std::collections::HashMap;
#[get("/")]
fn index(store : State<RwLock<Store>>) -> Template {
let mut context = HashMap::new();
let rg = store.read();
context.insert("records", &rg.parts);
Template::render("index", context)
}
#[post("/add", data="<record>")]
fn add_part(store : State<RwLock<Store>>, record : Form<store::Part>) -> Redirect {
store.write().add(record.into_inner());
Redirect::to(uri!(index))
}
fn main() {
rocket::ignite()
.attach(Template::fairing())
.manage(RwLock::new(Store::new()))
.mount("/", routes![index, add_part]).launch();
}

@ -0,0 +1,52 @@
use std::fs::{File, OpenOptions};
use std::io::{Read, Write, Error};
use std::path::Path;
use rocket::request::FromForm;
#[derive(Serialize,Deserialize)]
pub struct Store {
pub parts : Vec<Part>
}
#[derive(Serialize,Deserialize,FromForm)]
pub struct Part {
name : String,
quantity : usize,
location : String,
}
fn load_file_or(file : impl AsRef<Path>, def : String) -> String {
let mut file = match File::open(file) {
Ok(file) => file,
Err(_) => return def
};
let mut buf = String::new();
if file.read_to_string(&mut buf).is_err() {
return def;
}
buf
}
impl Store {
pub fn new() -> Self {
let mut file = load_file_or("inventory.json", "[]".to_string());
Store {
parts: serde_json::from_str(&file).unwrap(),
}
}
pub fn add(&mut self, part : Part) {
self.parts.push(part);
self.persist()
}
pub fn persist(&self) {
let mut file = OpenOptions::new().write(true).create(true).truncate(true).open("inventory.json").unwrap();
file.write(serde_json::to_string(&self.parts).unwrap().as_bytes()).unwrap();
}
}

@ -0,0 +1,16 @@
<!DOCTYPE html>
<form action="/add" method="POST">
Name: <input type="text" name="name"><br>
Qty: <input type="number" step="1" min="0" name="quantity"><br>
Location: <input type="text" name="location"><br>
<button type="submit">Add</button>
</form>
<ul>
{% for record in records %}
<li>
{{ record.name }} x {{ record.quantity }} in {{ record.location }}
</li>
{% endfor %}
</ul>
Loading…
Cancel
Save