Run rustfmt on all source files
This commit is contained in:
parent
67d55cadc4
commit
270cffa00e
|
@ -5,8 +5,8 @@ use super::super::NoteStore;
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct IndexTemplateContext<'a> {
|
struct IndexTemplateContext<'a> {
|
||||||
app_version: &'a str,
|
app_version: &'a str,
|
||||||
notes: Vec<HashMap<&'a str, &'a str>>
|
notes: Vec<HashMap<&'a str, &'a str>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/")]
|
#[get("/")]
|
||||||
|
@ -21,7 +21,7 @@ fn index(notes: State<NoteStore>) -> Template {
|
||||||
}
|
}
|
||||||
let context = IndexTemplateContext {
|
let context = IndexTemplateContext {
|
||||||
app_version: env!("CARGO_PKG_VERSION"),
|
app_version: env!("CARGO_PKG_VERSION"),
|
||||||
notes: note_kvs
|
notes: note_kvs,
|
||||||
};
|
};
|
||||||
Template::render("index", &context)
|
Template::render("index", &context)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,21 +12,21 @@ fn index(notes: State<NoteStore>) -> Option<Json<Vec<Note>>> {
|
||||||
#[get("/<note_id>", format = "text/html")]
|
#[get("/<note_id>", format = "text/html")]
|
||||||
fn show_html(note_id: String, notes: State<NoteStore>) -> Option<String> {
|
fn show_html(note_id: String, notes: State<NoteStore>) -> Option<String> {
|
||||||
let notes = notes.read().unwrap();
|
let notes = notes.read().unwrap();
|
||||||
let note = notes.iter().find( |note| note.id == note_id )?;
|
let note = notes.iter().find(|note| note.id == note_id)?;
|
||||||
Some(note.to_html())
|
Some(note.to_html())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[get("/<note_id>", format = "application/json")]
|
#[get("/<note_id>", format = "application/json")]
|
||||||
fn show_json(note_id: String, notes: State<NoteStore>) -> Option<Json<Note>> {
|
fn show_json(note_id: String, notes: State<NoteStore>) -> Option<Json<Note>> {
|
||||||
let notes = notes.read().unwrap();
|
let notes = notes.read().unwrap();
|
||||||
let note = notes.iter().find( |note| note.id == note_id )?;
|
let note = notes.iter().find(|note| note.id == note_id)?;
|
||||||
Some(Json(note.clone()))
|
Some(Json(note.clone()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[put("/<note_id>", format = "application/json", data = "<new_note>")]
|
#[put("/<note_id>", format = "application/json", data = "<new_note>")]
|
||||||
fn update(note_id: String, new_note: Json<Note>, notes: State<NoteStore>) -> Option<Json<Note>> {
|
fn update(note_id: String, new_note: Json<Note>, notes: State<NoteStore>) -> Option<Json<Note>> {
|
||||||
let mut notes = notes.write().unwrap();
|
let mut notes = notes.write().unwrap();
|
||||||
let note = notes.iter_mut().find( |note| note.id == note_id )?;
|
let note = notes.iter_mut().find(|note| note.id == note_id)?;
|
||||||
note.update_data(&new_note.data);
|
note.update_data(&new_note.data);
|
||||||
Some(Json(note.clone()))
|
Some(Json(note.clone()))
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,10 @@ mod tests {
|
||||||
assert_eq!(notes[0].id, "test");
|
assert_eq!(notes[0].id, "test");
|
||||||
assert_eq!(notes[0].index, 0);
|
assert_eq!(notes[0].index, 0);
|
||||||
assert_eq!(notes[0].name, "Test");
|
assert_eq!(notes[0].name, "Test");
|
||||||
assert_eq!(notes[0].data, "This is a test list\n\n* One\n* Two\n* Three\n");
|
assert_eq!(
|
||||||
|
notes[0].data,
|
||||||
|
"This is a test list\n\n* One\n* Two\n* Three\n"
|
||||||
|
);
|
||||||
// The mtime field can vary, don't test for it
|
// The mtime field can vary, don't test for it
|
||||||
// The path field is private, also don't test for it
|
// The path field is private, also don't test for it
|
||||||
|
|
||||||
|
@ -70,14 +73,16 @@ mod tests {
|
||||||
assert_eq!(res.status(), Status::Ok);
|
assert_eq!(res.status(), Status::Ok);
|
||||||
|
|
||||||
let body = res.body_string().unwrap();
|
let body = res.body_string().unwrap();
|
||||||
assert_eq!(body,
|
assert_eq!(
|
||||||
|
body,
|
||||||
r#"<p>This is a test list</p>
|
r#"<p>This is a test list</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>One</li>
|
<li>One</li>
|
||||||
<li>Two</li>
|
<li>Two</li>
|
||||||
<li>Three</li>
|
<li>Three</li>
|
||||||
</ul>
|
</ul>
|
||||||
"#);
|
"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -98,7 +103,10 @@ mod tests {
|
||||||
// The path field is private, also don't test for it
|
// The path field is private, also don't test for it
|
||||||
|
|
||||||
// Try to get a note that doesn't exist
|
// Try to get a note that doesn't exist
|
||||||
let res = client.get("/notes/doesntexit").header(Accept::JSON).dispatch();
|
let res = client
|
||||||
|
.get("/notes/doesntexit")
|
||||||
|
.header(Accept::JSON)
|
||||||
|
.dispatch();
|
||||||
assert_eq!(res.status(), Status::NotFound);
|
assert_eq!(res.status(), Status::NotFound);
|
||||||
|
|
||||||
// FIXME: Test that there is some kind of error in the JSON
|
// FIXME: Test that there is some kind of error in the JSON
|
||||||
|
@ -109,7 +117,10 @@ mod tests {
|
||||||
let client = Client::new(rocket(Some("test"))).unwrap();
|
let client = Client::new(rocket(Some("test"))).unwrap();
|
||||||
|
|
||||||
// Try to get the note and determine what to change it to
|
// Try to get the note and determine what to change it to
|
||||||
let mut res = client.get("/notes/updatable").header(Accept::JSON).dispatch();
|
let mut res = client
|
||||||
|
.get("/notes/updatable")
|
||||||
|
.header(Accept::JSON)
|
||||||
|
.dispatch();
|
||||||
let body = res.body_string().unwrap();
|
let body = res.body_string().unwrap();
|
||||||
let note = serde_json::from_str::<Note>(body.as_str()).unwrap();
|
let note = serde_json::from_str::<Note>(body.as_str()).unwrap();
|
||||||
assert_eq!(note.data, "Some content");
|
assert_eq!(note.data, "Some content");
|
||||||
|
@ -127,13 +138,15 @@ mod tests {
|
||||||
"name": "Updatable",
|
"name": "Updatable",
|
||||||
"path": "test/notes/updatablenote"
|
"path": "test/notes/updatablenote"
|
||||||
});
|
});
|
||||||
let res = client.put("/notes/updatable")
|
let res = client
|
||||||
|
.put("/notes/updatable")
|
||||||
.header(ContentType::JSON)
|
.header(ContentType::JSON)
|
||||||
.body(new_json.to_string())
|
.body(new_json.to_string())
|
||||||
.dispatch();
|
.dispatch();
|
||||||
assert_eq!(res.status(), Status::Ok);
|
assert_eq!(res.status(), Status::Ok);
|
||||||
|
|
||||||
let mut res = client.get("/notes/updatable")
|
let mut res = client
|
||||||
|
.get("/notes/updatable")
|
||||||
.header(Accept::JSON)
|
.header(Accept::JSON)
|
||||||
.dispatch();
|
.dispatch();
|
||||||
let body = res.body_string().unwrap();
|
let body = res.body_string().unwrap();
|
||||||
|
@ -142,28 +155,32 @@ mod tests {
|
||||||
|
|
||||||
// ... and change it back
|
// ... and change it back
|
||||||
*new_json.get_mut("data").unwrap() = json!("Some content");
|
*new_json.get_mut("data").unwrap() = json!("Some content");
|
||||||
let res = client.put("/notes/updatable")
|
let res = client
|
||||||
|
.put("/notes/updatable")
|
||||||
.header(ContentType::JSON)
|
.header(ContentType::JSON)
|
||||||
.body(new_json.to_string())
|
.body(new_json.to_string())
|
||||||
.dispatch();
|
.dispatch();
|
||||||
assert_eq!(res.status(), Status::Ok);
|
assert_eq!(res.status(), Status::Ok);
|
||||||
|
|
||||||
// Try to change a note that doesn't exist
|
// Try to change a note that doesn't exist
|
||||||
let res = client.put("/notes/doesntexit")
|
let res = client
|
||||||
|
.put("/notes/doesntexit")
|
||||||
.header(ContentType::JSON)
|
.header(ContentType::JSON)
|
||||||
.body(new_json.to_string())
|
.body(new_json.to_string())
|
||||||
.dispatch();
|
.dispatch();
|
||||||
assert_eq!(res.status(), Status::NotFound);
|
assert_eq!(res.status(), Status::NotFound);
|
||||||
|
|
||||||
// Try to change a note without a proper body
|
// Try to change a note without a proper body
|
||||||
let res = client.put("/notes/updatable")
|
let res = client
|
||||||
|
.put("/notes/updatable")
|
||||||
.header(ContentType::JSON)
|
.header(ContentType::JSON)
|
||||||
.body(r#"{}"#)
|
.body(r#"{}"#)
|
||||||
.dispatch();
|
.dispatch();
|
||||||
assert_eq!(res.status(), Status::BadRequest);
|
assert_eq!(res.status(), Status::BadRequest);
|
||||||
|
|
||||||
// Try to change a note without a proper type (i.e. not JSON)
|
// Try to change a note without a proper type (i.e. not JSON)
|
||||||
let res = client.put("/notes/updatable")
|
let res = client
|
||||||
|
.put("/notes/updatable")
|
||||||
.header(ContentType::Plain)
|
.header(ContentType::Plain)
|
||||||
.body("foo bar baz")
|
.body("foo bar baz")
|
||||||
.dispatch();
|
.dispatch();
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::path::{Path,PathBuf};
|
use std::path::{Path, PathBuf};
|
||||||
use rocket::response::NamedFile;
|
use rocket::response::NamedFile;
|
||||||
|
|
||||||
#[get("/<path..>", rank = 5)]
|
#[get("/<path..>", rank = 5)]
|
||||||
|
|
24
src/main.rs
24
src/main.rs
|
@ -6,8 +6,10 @@ extern crate glob;
|
||||||
extern crate inflector;
|
extern crate inflector;
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
extern crate rocket_contrib;
|
extern crate rocket_contrib;
|
||||||
#[macro_use] extern crate serde_derive;
|
#[macro_use]
|
||||||
#[macro_use] extern crate serde_json;
|
extern crate serde_derive;
|
||||||
|
#[macro_use]
|
||||||
|
extern crate serde_json;
|
||||||
|
|
||||||
mod handlers;
|
mod handlers;
|
||||||
mod models;
|
mod models;
|
||||||
|
@ -21,11 +23,19 @@ fn rocket(notes_path: Option<&str>) -> Rocket {
|
||||||
let notes = models::note::Note::load_all(notes_path);
|
let notes = models::note::Note::load_all(notes_path);
|
||||||
rocket::ignite()
|
rocket::ignite()
|
||||||
.manage(RwLock::new(notes))
|
.manage(RwLock::new(notes))
|
||||||
.mount("/", routes![handlers::home::index,
|
.mount(
|
||||||
handlers::static_files::all])
|
"/",
|
||||||
.mount("/notes", routes![handlers::note::index,
|
routes![handlers::home::index, handlers::static_files::all],
|
||||||
handlers::note::show_html, handlers::note::show_json,
|
)
|
||||||
handlers::note::update])
|
.mount(
|
||||||
|
"/notes",
|
||||||
|
routes![
|
||||||
|
handlers::note::index,
|
||||||
|
handlers::note::show_html,
|
||||||
|
handlers::note::show_json,
|
||||||
|
handlers::note::update
|
||||||
|
],
|
||||||
|
)
|
||||||
.attach(rocket_contrib::Template::fairing())
|
.attach(rocket_contrib::Template::fairing())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,7 +20,7 @@ pub struct Note {
|
||||||
/// The name of the note, i.e. the person it is for
|
/// The name of the note, i.e. the person it is for
|
||||||
pub name: String,
|
pub name: String,
|
||||||
/// The path to the note file
|
/// The path to the note file
|
||||||
path: PathBuf
|
path: PathBuf,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Note {
|
impl Note {
|
||||||
|
@ -34,13 +34,15 @@ impl Note {
|
||||||
comrak::markdown_to_html(&self.data, &options)
|
comrak::markdown_to_html(&self.data, &options)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_data(&mut self, data : &String) {
|
pub fn update_data(&mut self, data: &String) {
|
||||||
let mut file = File::create(&self.path)
|
let mut file = File::create(&self.path).expect(&format!(
|
||||||
.expect(&format!("Cannot open note file {}",
|
"Cannot open note file {}",
|
||||||
self.path.to_str().unwrap()));
|
self.path.to_str().unwrap()
|
||||||
file.write_all(data.as_bytes())
|
));
|
||||||
.expect(&format!("Cannot write note file {}",
|
file.write_all(data.as_bytes()).expect(&format!(
|
||||||
self.path.to_str().unwrap()));
|
"Cannot write note file {}",
|
||||||
|
self.path.to_str().unwrap()
|
||||||
|
));
|
||||||
|
|
||||||
self.data = data.clone();
|
self.data = data.clone();
|
||||||
let metadata = file.metadata().unwrap();
|
let metadata = file.metadata().unwrap();
|
||||||
|
@ -48,21 +50,21 @@ impl Note {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_all(note_path: Option<&str>) -> Vec<Self> {
|
pub fn load_all(note_path: Option<&str>) -> Vec<Self> {
|
||||||
let mut notes : Vec<Note> = vec![];
|
let mut notes: Vec<Note> = vec![];
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
let path_glob = match note_path {
|
let path_glob = match note_path {
|
||||||
Some(dir) => format!("{}/notes/*.note", dir),
|
Some(dir) => format!("{}/notes/*.note", dir),
|
||||||
None => format!("notes/*.note")
|
None => format!("notes/*.note"),
|
||||||
};
|
};
|
||||||
for entry in glob(path_glob.as_str()).unwrap().filter_map(Result::ok) {
|
for entry in glob(path_glob.as_str()).unwrap().filter_map(Result::ok) {
|
||||||
let file_name = entry.file_name().unwrap().to_str().unwrap();
|
let file_name = entry.file_name().unwrap().to_str().unwrap();
|
||||||
let name = match file_name.find('.') {
|
let name = match file_name.find('.') {
|
||||||
Some(index) => &file_name[0..index],
|
Some(index) => &file_name[0..index],
|
||||||
None => "unknown"
|
None => "unknown",
|
||||||
};
|
};
|
||||||
let mut data = String::new();
|
let mut data = String::new();
|
||||||
let mut file = File::open(&entry)
|
let mut file =
|
||||||
.expect(&format!("Cannot open note file {}", file_name));
|
File::open(&entry).expect(&format!("Cannot open note file {}", file_name));
|
||||||
file.read_to_string(&mut data)
|
file.read_to_string(&mut data)
|
||||||
.expect(&format!("Cannot read note file {}", file_name));
|
.expect(&format!("Cannot read note file {}", file_name));
|
||||||
let metadata = file.metadata()
|
let metadata = file.metadata()
|
||||||
|
@ -70,11 +72,11 @@ impl Note {
|
||||||
|
|
||||||
let mut note = Note {
|
let mut note = Note {
|
||||||
id: String::from(name),
|
id: String::from(name),
|
||||||
index : index,
|
index: index,
|
||||||
data: data,
|
data: data,
|
||||||
mtime: metadata.modified().unwrap(),
|
mtime: metadata.modified().unwrap(),
|
||||||
name: String::from(name).to_title_case(),
|
name: String::from(name).to_title_case(),
|
||||||
path: entry.clone()
|
path: entry.clone(),
|
||||||
};
|
};
|
||||||
notes.push(note);
|
notes.push(note);
|
||||||
index += 1;
|
index += 1;
|
||||||
|
@ -90,30 +92,31 @@ mod tests {
|
||||||
#[test]
|
#[test]
|
||||||
fn loads_all_notes() {
|
fn loads_all_notes() {
|
||||||
let notes = Note::load_all(Some("test"));
|
let notes = Note::load_all(Some("test"));
|
||||||
let note_ids: Vec<&str> = notes.iter()
|
let note_ids: Vec<&str> = notes.iter().map(|note| note.id.as_ref()).collect();
|
||||||
.map(|note| note.id.as_ref()).collect();
|
|
||||||
assert_eq!(note_ids, vec!["test", "updatable"]);
|
assert_eq!(note_ids, vec!["test", "updatable"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn converts_to_html() {
|
fn converts_to_html() {
|
||||||
let notes = Note::load_all(Some("test"));
|
let notes = Note::load_all(Some("test"));
|
||||||
let note = notes.iter()
|
let note = notes.iter().find(|note| note.id == "test").unwrap();
|
||||||
.find(|note| note.id == "test")
|
assert_eq!(
|
||||||
.unwrap();
|
note.to_html(),
|
||||||
assert_eq!(note.to_html(), r#"<p>This is a test list</p>
|
r#"<p>This is a test list</p>
|
||||||
<ul>
|
<ul>
|
||||||
<li>One</li>
|
<li>One</li>
|
||||||
<li>Two</li>
|
<li>Two</li>
|
||||||
<li>Three</li>
|
<li>Three</li>
|
||||||
</ul>
|
</ul>
|
||||||
"#);
|
"#
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn updates_data() {
|
fn updates_data() {
|
||||||
let mut notes = Note::load_all(Some("test"));
|
let mut notes = Note::load_all(Some("test"));
|
||||||
let note = notes.iter_mut()
|
let note = notes
|
||||||
|
.iter_mut()
|
||||||
.find(|note| note.id == "updatable")
|
.find(|note| note.id == "updatable")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(note.data, "Some content");
|
assert_eq!(note.data, "Some content");
|
||||||
|
@ -126,7 +129,8 @@ mod tests {
|
||||||
// Verify that the data is written to the file of the note by
|
// Verify that the data is written to the file of the note by
|
||||||
// loading them again
|
// loading them again
|
||||||
let mut notes = Note::load_all(Some("test"));
|
let mut notes = Note::load_all(Some("test"));
|
||||||
let note = notes.iter_mut()
|
let note = notes
|
||||||
|
.iter_mut()
|
||||||
.find(|note| note.id == "updatable")
|
.find(|note| note.id == "updatable")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(note.data, new_data);
|
assert_eq!(note.data, new_data);
|
||||||
|
|
Loading…
Reference in New Issue