#![feature(plugin, decl_macro)] #![plugin(rocket_codegen)] #[macro_use] extern crate rocket; #[macro_use] extern crate lazy_static; #[macro_use] extern crate json; extern crate rocket_cors; #[macro_use] extern crate serde_json; extern crate json_patch; use std::io::prelude::*; use std::fs::File; use std::path::{Path, PathBuf}; use std::thread; use std::time::Duration; use std::sync::Mutex; use rocket::response::NamedFile; use json_patch::patch; use serde_json::from_str; use serde_json::to_string; use json_patch::merge; lazy_static! { static ref OBJECT: Mutex = Mutex::new(String::from("{}")); } // send out the stored object #[get("/")] fn get() -> String { match OBJECT.lock() { Ok(obj) => { println!("MATCH obj {:?}", *obj); let result: &String = &*obj; result.clone() }, _ => { println!("UNLOCK failed"); String::from("{}") } } } //set the storage #[get("/")] fn set(obj: String) -> String { // let json_result = json::parse(obj.to_owned().as_str()); // let json_result: serde_json::Value = from_str(obj.to_owned().as_str()); let json_result: Result = from_str(obj.to_owned().as_str()); match json_result { Ok(json_from_web) => { let mut locked_obj = OBJECT.lock().unwrap(); // let current_object = json::parse(&locked_obj); let mut parsed_object: Result = from_str(&locked_obj); match parsed_object { Ok(mut json_object) => { println!("{:?}", json_object); merge(&mut json_object, &json_from_web); *locked_obj = to_string(&json_object).unwrap(); println!("JSON MERGE {:?}", json_object); }, Err(e) => { // The db is somehow corrupted, just put in what we got from the web println!("Invalid json in db {:?}", e); *locked_obj = to_string(&json_from_web).unwrap(); } } println!("GOT {:?}", obj); println!("JSON INCOMING {:?}", json_from_web); String::from("Done") }, Err(_e) => String::from("Invalid Json") } } // Static file serving #[get("/")] fn static_content(file: PathBuf) -> NamedFile { let f = NamedFile::open(Path::new("static/").join(file)); match f { Ok(result) => result, Err(_e) => NamedFile::open("static/err.html").unwrap() } } // periodically dump the database fn disk_committer() { thread::spawn(|| { loop { thread::sleep(Duration::from_secs(2)); match OBJECT.lock() { Ok(obj) => { let result: &String = &*obj; let mut buffer = File::create("db").unwrap(); buffer.write(result.as_bytes()).unwrap(); // println!("Committing to disk"); }, _ => () } } }); } fn read_db() { let dbfile = File::open("db"); match dbfile { Ok(mut f) => { let mut contents = String::new(); f.read_to_string(&mut contents).expect("{}"); let mut data = OBJECT.lock().unwrap(); *data = contents; }, Err(e) => println!("Could not load db file {:?}", e) } } fn main() { // let (allowed_origins, failed_origins) = AllowedOrigins::some(&["https://www.acme.com"]); // assert!(failed_origins.is_empty()); // // You can also deserialize this // let options = rocket_cors::Cors { // allowed_origins: allowed_origins, // allowed_methods: vec![Method::Get].into_iter().map(From::from).collect(), // allowed_headers: AllowedHeaders::some(&["Authorization", "Accept"]), // allow_credentials: true, // ..Default::default() // }; // let default = rocket_cors::Cors::default(); // Load from db read_db(); disk_committer(); rocket::ignite() .mount("/set", routes![set]) .mount("/get", routes![get]) // .mount("/test", routes![test]) .mount("/static", routes![static_content]) // .attach(default) .launch(); }