first experiments with rocket
This commit is contained in:
@@ -0,0 +1,4 @@
|
||||
/target
|
||||
**/*.rs.bk
|
||||
.idea/
|
||||
inventory.json
|
||||
Generated
+6
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="NodePackageJsonFileManager">
|
||||
<packageJsonPaths />
|
||||
</component>
|
||||
</project>
|
||||
Generated
+2
@@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
||||
Generated
+1289
File diff suppressed because it is too large
Load Diff
+26
@@ -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
|
||||
+39
@@ -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>
|
||||
Reference in New Issue
Block a user