Run cargo fmt

This commit is contained in:
~erin 2022-01-24 07:52:04 -05:00
parent e7d99fed96
commit ecef893859
No known key found for this signature in database
GPG Key ID: DA70E064A8C70F44
6 changed files with 134 additions and 89 deletions

View File

@ -7,7 +7,7 @@ use captcha::filters::{Grid, Noise, Wave};
use captcha::Captcha; use captcha::Captcha;
use std::path::Path; use std::path::Path;
use crate::structures::{CaptchaAnswer}; use crate::structures::CaptchaAnswer;
use rocket::{form::Form, http::Cookie, http::CookieJar}; use rocket::{form::Form, http::Cookie, http::CookieJar};
// Create a new captcha image // Create a new captcha image
@ -42,9 +42,10 @@ pub fn return_captcha(cookies: &CookieJar<'_>) -> File {
let file = File::open(&("/tmp/captcha".to_owned() + &captcha_text + ".png")); // Open the captcha image file let file = File::open(&("/tmp/captcha".to_owned() + &captcha_text + ".png")); // Open the captcha image file
info!("created new captcha {}", captcha_text); // Print the captcha text info!("created new captcha {}", captcha_text); // Print the captcha text
cookies.add_private(Cookie::new( // Set the token as a private cookie cookies.add_private(Cookie::new(
// Set the token as a private cookie
"token", // Add a cookie to store the captcha answer "token", // Add a cookie to store the captcha answer
captcha_text captcha_text,
)); ));
return file.unwrap(); // Return the captcha image return file.unwrap(); // Return the captcha image

View File

@ -1,11 +1,11 @@
use chrono::Utc;
use rss::{ChannelBuilder, Guid, Item, ItemBuilder};
use std::env;
use std::fs::File; use std::fs::File;
use std::fs::OpenOptions; use std::fs::OpenOptions;
use std::io::prelude::*; use std::io::prelude::*;
use std::path::PathBuf; use std::path::PathBuf;
use std::env;
use uuid::Uuid; use uuid::Uuid;
use chrono::Utc;
use rss::{ChannelBuilder, ItemBuilder, Item, Guid};
use crate::structures::*; use crate::structures::*;
@ -24,14 +24,17 @@ pub fn write_feed(lang: &str) {
let recipes = db_get_all_recipes(); let recipes = db_get_all_recipes();
let mut feed_items: Vec<Item> = Vec::new(); let mut feed_items: Vec<Item> = Vec::new();
for i in recipes { for i in recipes {
feed_items.push(ItemBuilder::default() feed_items.push(
.title(i.name) ItemBuilder::default()
.link(format!("/{}", &i.shortcode)) .title(i.name)
.guid(Guid { .link(format!("/{}", &i.shortcode))
value: i.id.as_simple().to_string(), .guid(Guid {
permalink: false}) value: i.id.as_simple().to_string(),
.pub_date(i.posted_date.to_string()) permalink: false,
.build()); })
.pub_date(i.posted_date.to_string())
.build(),
);
} }
let channel = ChannelBuilder::default() let channel = ChannelBuilder::default()
@ -53,11 +56,12 @@ pub fn write_html(html: String, lang: &str, shortcode: Option<&str>) {
let mut path = PathBuf::new(); let mut path = PathBuf::new();
path.push("static"); // base path for web content path.push("static"); // base path for web content
path.push(lang); // not really that useful right now path.push(lang); // not really that useful right now
match shortcode { // If there's a shortcode (for a recipe), use that path match shortcode {
// If there's a shortcode (for a recipe), use that path
Some(short) => { Some(short) => {
path.push(short); path.push(short);
path.push("index.html"); path.push("index.html");
}, }
None => path.push("index.html"), // Otherwise just write to the main index None => path.push("index.html"), // Otherwise just write to the main index
} }
@ -66,10 +70,7 @@ pub fn write_html(html: String, lang: &str, shortcode: Option<&str>) {
std::fs::create_dir_all(prefix).unwrap(); std::fs::create_dir_all(prefix).unwrap();
// Open file in write-only mode // Open file in write-only mode
let mut file = match OpenOptions::new() let mut file = match OpenOptions::new().write(true).create(true).open(&path) {
.write(true)
.create(true)
.open(&path) {
Err(why) => panic!("couldn't create file: {}", why), Err(why) => panic!("couldn't create file: {}", why),
Ok(file) => file, Ok(file) => file,
}; };
@ -91,7 +92,7 @@ pub fn open_database(keyspace: &str) -> Option<sled::Tree> {
tmp_path.push(".local/share/catgirl-cooking"); tmp_path.push(".local/share/catgirl-cooking");
tmp_path.push("database"); tmp_path.push("database");
tmp_path tmp_path
}, }
Err(e) => { Err(e) => {
panic!("failed to get key: {}", e); panic!("failed to get key: {}", e);
} }
@ -107,7 +108,10 @@ pub fn open_database(keyspace: &str) -> Option<sled::Tree> {
let database: Option<sled::Tree> = match db.open_tree(keyspace) { let database: Option<sled::Tree> = match db.open_tree(keyspace) {
Ok(tree) => Some(tree), Ok(tree) => Some(tree),
Err(e) => { println!("error in opening Tree: {}", e); None }, Err(e) => {
println!("error in opening Tree: {}", e);
None
}
}; };
return database; return database;
} }
@ -139,8 +143,8 @@ pub fn db_get_recipe(id: Uuid) -> Recipe {
}; };
let db_entry = match db.get(id.as_simple().to_string()) { let db_entry = match db.get(id.as_simple().to_string()) {
Ok(entry) => entry, Ok(entry) => entry,
Err(error) => panic!("failed to get recipe: {}", error), Err(error) => panic!("failed to get recipe: {}", error),
}; };
if let Some(entry) = db_entry { if let Some(entry) = db_entry {
@ -159,12 +163,12 @@ pub fn db_get_all_recipes() -> Vec<Recipe> {
Some(database) => database, Some(database) => database,
None => panic!(), None => panic!(),
}; };
let first_key = match db.first() { let first_key = match db.first() {
Ok(pair) => match pair { Ok(pair) => match pair {
Some(key) => key.0, Some(key) => key.0,
None => panic!("error getting first key"), None => panic!("error getting first key"),
} },
Err(error) => panic!("error getting first key: {}", error), Err(error) => panic!("error getting first key: {}", error),
}; };
@ -180,7 +184,7 @@ pub fn db_get_all_recipes() -> Vec<Recipe> {
Err(error) => panic!("failed to deserialize entry: {}", error), Err(error) => panic!("failed to deserialize entry: {}", error),
} }
recipes_list.push(read_entry); recipes_list.push(read_entry);
}, }
None => break, None => break,
} }
} }
@ -193,12 +197,12 @@ pub fn db_get_last_recipe() -> Recipe {
Some(database) => database, Some(database) => database,
None => panic!(), None => panic!(),
}; };
let last_key = match db.last() { let last_key = match db.last() {
Ok(pair) => match pair { Ok(pair) => match pair {
Some(key) => key.0, Some(key) => key.0,
None => panic!("error getting first key"), None => panic!("error getting first key"),
} },
Err(error) => panic!("error getting first key: {}", error), Err(error) => panic!("error getting first key: {}", error),
}; };
@ -209,4 +213,4 @@ pub fn db_get_last_recipe() -> Recipe {
} }
return read_entry; return read_entry;
} }

View File

@ -1,20 +1,20 @@
use build_html::{self, Html, HtmlContainer, ContainerType, Container}; use build_html::{self, Container, ContainerType, Html, HtmlContainer};
use uuid::Uuid; use uuid::Uuid;
mod structures;
mod io;
mod tests;
mod networking;
mod captcha; mod captcha;
mod io;
mod networking;
mod structures;
mod tests;
#[macro_use] #[macro_use]
extern crate rocket; extern crate rocket;
use rocket::fairing::{Fairing, Info, Kind}; use rocket::fairing::{Fairing, Info, Kind};
use rocket::{http::Header, Request, Response};
use rocket::fs::FileServer; use rocket::fs::FileServer;
use rocket::{http::Header, Request, Response};
use crate::networking::*;
use crate::captcha::*; use crate::captcha::*;
use crate::networking::*;
fn construct_main_page() { fn construct_main_page() {
// Create the footer // Create the footer
@ -29,11 +29,12 @@ fn construct_main_page() {
// Create (test) lists of tags & recipes // Create (test) lists of tags & recipes
let tags: Vec<&str> = vec!["breakfast", "apples", "cheese", "vegan", "vegetarian"]; let tags: Vec<&str> = vec!["breakfast", "apples", "cheese", "vegan", "vegetarian"];
let recipes = io::db_get_all_recipes(); let recipes = io::db_get_all_recipes();
// Create HTML string of tags // Create HTML string of tags
let mut tags_html = String::new(); // Create custom html string for tags let mut tags_html = String::new(); // Create custom html string for tags
tags_html.push_str(r#"<p>Tags: "#); // Begin paragraph element tags_html.push_str(r#"<p>Tags: "#); // Begin paragraph element
for x in tags { // Go through the list of tags for x in tags {
// Go through the list of tags
tags_html.push_str(format!("<a href='{}'>{}</a>,", x, x).as_str()); // Append the tags as a link tags_html.push_str(format!("<a href='{}'>{}</a>,", x, x).as_str()); // Append the tags as a link
} }
tags_html.push_str(r#"</p>"#); // End the paragraph tags_html.push_str(r#"</p>"#); // End the paragraph
@ -52,8 +53,14 @@ fn construct_main_page() {
.with_head_link("favicon.ico", "icon") // Favicon .with_head_link("favicon.ico", "icon") // Favicon
.with_stylesheet("style.css") // Link stylesheet .with_stylesheet("style.css") // Link stylesheet
.with_meta(vec![("charset", "UTF-8")]) .with_meta(vec![("charset", "UTF-8")])
.with_meta(vec![("name", "viewport"), ("content", "width=device-width, initial-scale=1")]) // Display stuff .with_meta(vec![
.with_meta(vec![("name", "description"), ("content", structures::DESCRIPTION)]) // Add the description ("name", "viewport"),
("content", "width=device-width, initial-scale=1"),
]) // Display stuff
.with_meta(vec![
("name", "description"),
("content", structures::DESCRIPTION),
]) // Add the description
.with_title(structures::TITLE) .with_title(structures::TITLE)
.with_header(1, structures::HEADER) .with_header(1, structures::HEADER)
.with_raw(r#"<hr>"#) .with_raw(r#"<hr>"#)
@ -81,7 +88,7 @@ fn rebuild() {
#[launch] #[launch]
fn rocket() -> _ { fn rocket() -> _ {
rebuild(); rebuild();
// Launch rocket // Launch rocket
let _config = sled::Config::default() let _config = sled::Config::default()
.use_compression(true) .use_compression(true)
@ -90,12 +97,7 @@ fn rocket() -> _ {
rocket::build() rocket::build()
.mount( .mount(
"/api", "/api",
routes![ routes![test, return_captcha, check_captcha, new_recipe],
test,
return_captcha,
check_captcha,
new_recipe
],
) )
.mount("/", FileServer::from("static/en/")) .mount("/", FileServer::from("static/en/"))
} }

View File

@ -1,5 +1,5 @@
use rocket::form::Form;
use crate::structures::{RecipeForm, Tag}; use crate::structures::{RecipeForm, Tag};
use rocket::form::Form;
#[get("/test")] #[get("/test")]
pub fn test() -> String { pub fn test() -> String {
@ -10,15 +10,12 @@ pub fn parse_tags(tags: String) -> Vec<Tag> {
let split: Vec<&str> = tags.split(",").collect(); let split: Vec<&str> = tags.split(",").collect();
let mut tags_vec: Vec<Tag> = Vec::new(); let mut tags_vec: Vec<Tag> = Vec::new();
for i in split { for i in split {
tags_vec.push(Tag::new(i tags_vec.push(Tag::new(i.replace(" ", "").replace("#", "")));
.replace(" ", "")
.replace("#", "")));
} }
return tags_vec; return tags_vec;
} }
#[post("/new-recipe", data = "<recipe>")] #[post("/new-recipe", data = "<recipe>")]
pub fn new_recipe(recipe: Form<RecipeForm>) -> String { pub fn new_recipe(recipe: Form<RecipeForm>) -> String {
return recipe.recipe_name.to_owned(); return recipe.recipe_name.to_owned();
} }

View File

@ -1,9 +1,9 @@
use uuid::Uuid; use build_html::{self, Container, ContainerType, Html, HtmlContainer, HtmlPage};
use chrono::prelude::*; use chrono::prelude::*;
use serde_derive::{Deserialize, Serialize};
use build_html::{self, Html, HtmlContainer, ContainerType, Container, HtmlPage};
use std::fmt;
use rocket::form::Form; use rocket::form::Form;
use serde_derive::{Deserialize, Serialize};
use std::fmt;
use uuid::Uuid;
use crate::io::write_html; use crate::io::write_html;
@ -121,25 +121,29 @@ pub struct RecipeForm {
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct Recipe { pub struct Recipe {
pub id: Uuid, // Unique recipe ID pub id: Uuid, // Unique recipe ID
pub name: String, // Full recipe name pub name: String, // Full recipe name
pub shortcode: String, pub shortcode: String,
pub prep_time: (i32, TimeUnits), // Preparation time: (value, units) pub prep_time: (i32, TimeUnits), // Preparation time: (value, units)
pub cooking_time: (i32, TimeUnits), // Cooking time: (value, units) pub cooking_time: (i32, TimeUnits), // Cooking time: (value, units)
pub servings: u8, // How many servinge the recipe makes pub servings: u8, // How many servinge the recipe makes
pub ingredients: Vec<(i32, MeasurementUnits, String)>, // Vector of ingredients: (value, units, name) pub ingredients: Vec<(i32, MeasurementUnits, String)>, // Vector of ingredients: (value, units, name)
pub directions: Vec<(u16, String)>, // List of instructions: (step #, details) pub directions: Vec<(u16, String)>, // List of instructions: (step #, details)
pub attribution: String, // Author name pub attribution: String, // Author name
pub posted_date: DateTime<Utc>, // Date the recipe was first posted pub posted_date: DateTime<Utc>, // Date the recipe was first posted
pub edited_date: Option<DateTime<Utc>>, // Date the recipe was last edited pub edited_date: Option<DateTime<Utc>>, // Date the recipe was last edited
pub tags: Option<Vec<Tag>>, // List of tags pub tags: Option<Vec<Tag>>, // List of tags
} }
impl Recipe { impl Recipe {
pub fn example(name: &str, time: i32, directions: Vec<&str>, ingredients: Vec<&str>) -> Recipe { pub fn example(name: &str, time: i32, directions: Vec<&str>, ingredients: Vec<&str>) -> Recipe {
let mut ingredients_list: Vec<(i32, MeasurementUnits, String)> = Vec::new(); let mut ingredients_list: Vec<(i32, MeasurementUnits, String)> = Vec::new();
for i in 0..ingredients.len() { for i in 0..ingredients.len() {
ingredients_list.push((i.try_into().unwrap(), MeasurementUnits::Litres, ingredients[i].to_string())); ingredients_list.push((
i.try_into().unwrap(),
MeasurementUnits::Litres,
ingredients[i].to_string(),
));
} }
let mut directions_list: Vec<(u16, String)> = Vec::new(); let mut directions_list: Vec<(u16, String)> = Vec::new();
@ -163,7 +167,16 @@ impl Recipe {
} }
} }
pub fn new(name: String, prep_time: (i32, TimeUnits), cooking_time: (i32, TimeUnits), servings: u8, ingredients: Vec<(i32, MeasurementUnits, String)>, directions: Vec<String>, attribution: String, tags: Option<Vec<Tag>>) -> Recipe { pub fn new(
name: String,
prep_time: (i32, TimeUnits),
cooking_time: (i32, TimeUnits),
servings: u8,
ingredients: Vec<(i32, MeasurementUnits, String)>,
directions: Vec<String>,
attribution: String,
tags: Option<Vec<Tag>>,
) -> Recipe {
let mut directions_list: Vec<(u16, String)> = Vec::new(); let mut directions_list: Vec<(u16, String)> = Vec::new();
for i in 0..directions.len() { for i in 0..directions.len() {
directions_list.push((i.try_into().unwrap(), directions[i].to_string())); directions_list.push((i.try_into().unwrap(), directions[i].to_string()));
@ -198,21 +211,27 @@ impl Recipe {
// Metadata // Metadata
let meta = Container::new(ContainerType::UnorderedList) let meta = Container::new(ContainerType::UnorderedList)
.with_attributes(vec![("class", "recipe")]) .with_attributes(vec![("class", "recipe")])
.with_paragraph(format!("<b>⏲️ Preparation time: </b> {} {}", &self.prep_time.0, &self.prep_time.1)) .with_paragraph(format!(
.with_paragraph(format!("<b>🍳 Cooking time:</b> {} {}", &self.cooking_time.0, &self.cooking_time.1)) "<b>⏲️ Preparation time: </b> {} {}",
&self.prep_time.0, &self.prep_time.1
))
.with_paragraph(format!(
"<b>🍳 Cooking time:</b> {} {}",
&self.cooking_time.0, &self.cooking_time.1
))
.with_paragraph(format!("<b>🍽️ Servings:</b> {}", &self.servings)); .with_paragraph(format!("<b>🍽️ Servings:</b> {}", &self.servings));
// Ingredients // Ingredients
let mut ingredients_container = Container::new(ContainerType::UnorderedList) let mut ingredients_container =
.with_attributes(vec![("class", "recipe")]); Container::new(ContainerType::UnorderedList).with_attributes(vec![("class", "recipe")]);
for i in &self.ingredients { for i in &self.ingredients {
let ingredient = format!("{} {} {}", &i.0, &i.1, &i.2); let ingredient = format!("{} {} {}", &i.0, &i.1, &i.2);
ingredients_container.add_paragraph(ingredient); ingredients_container.add_paragraph(ingredient);
} }
// Directions // Directions
let mut directions_container = Container::new(ContainerType::OrderedList) let mut directions_container =
.with_attributes(vec![("class", "recipe")]); Container::new(ContainerType::OrderedList).with_attributes(vec![("class", "recipe")]);
for n in &self.directions { for n in &self.directions {
directions_container.add_paragraph(&n.1); directions_container.add_paragraph(&n.1);
} }
@ -223,16 +242,20 @@ impl Recipe {
match &self.tags { match &self.tags {
Some(list) => { Some(list) => {
for x in 0..list.len() { for x in 0..list.len() {
if x != list.len()-1 { if x != list.len() - 1 {
tags_html.push_str(format!("<a href='/tags/{}'>#{}</a>,", list[x].1, list[x].1).as_str()); tags_html.push_str(
format!("<a href='/tags/{}'>#{}</a>,", list[x].1, list[x].1).as_str(),
);
} else { } else {
tags_html.push_str(format!("<a href='/tags/{}'>#{}</a>", list[x].1, list[x].1).as_str()); tags_html.push_str(
format!("<a href='/tags/{}'>#{}</a>", list[x].1, list[x].1).as_str(),
);
} }
} }
}, }
None => { None => {
tags_html.push_str(r#"no tags!! :o"#); tags_html.push_str(r#"no tags!! :o"#);
}, }
} }
tags_html.push_str(r#"</i></p>"#); tags_html.push_str(r#"</i></p>"#);
@ -243,8 +266,9 @@ impl Recipe {
"<p><b>Last edited on: </b><i>{}-{}-{}</i></p>", "<p><b>Last edited on: </b><i>{}-{}-{}</i></p>",
date.year(), date.year(),
date.month(), date.month(),
date.day()) date.day()
}, )
}
None => "<p><i>No edits</o></p>".to_string(), None => "<p><i>No edits</o></p>".to_string(),
}; };
@ -253,7 +277,10 @@ impl Recipe {
.with_head_link("/favicon.ico", "icon") // Favicon .with_head_link("/favicon.ico", "icon") // Favicon
.with_stylesheet("/style.css") // Link stylesheet .with_stylesheet("/style.css") // Link stylesheet
.with_meta(vec![("charset", "UTF-8")]) .with_meta(vec![("charset", "UTF-8")])
.with_meta(vec![("name", "viewport"), ("content", "width=device-width, initial-scale=1")]) // Display stuff .with_meta(vec![
("name", "viewport"),
("content", "width=device-width, initial-scale=1"),
]) // Display stuff
.with_meta(vec![("name", "description"), ("content", DESCRIPTION)]) // Add the description .with_meta(vec![("name", "description"), ("content", DESCRIPTION)]) // Add the description
.with_title(TITLE) .with_title(TITLE)
.with_header(1, &self.name) .with_header(1, &self.name)
@ -270,12 +297,13 @@ impl Recipe {
"<p><b>Recipe added on: </b><i>{}-{}-{}</i></p>", "<p><b>Recipe added on: </b><i>{}-{}-{}</i></p>",
&self.posted_date.year(), &self.posted_date.year(),
&self.posted_date.month(), &self.posted_date.month(),
&self.posted_date.day())) &self.posted_date.day()
))
.with_raw(edit_date) .with_raw(edit_date)
.with_container(footer); .with_container(footer);
write_html(recipe_page.to_html_string(), "en", Some(&self.shortcode)); write_html(recipe_page.to_html_string(), "en", Some(&self.shortcode));
} }
} }
pub fn construct_shortcode(full_name: String) -> String { pub fn construct_shortcode(full_name: String) -> String {

View File

@ -1,8 +1,8 @@
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
// Note this useful idiom: importing names from outer (for mod tests) scope. // Note this useful idiom: importing names from outer (for mod tests) scope.
use crate::networking::parse_tags;
use crate::structures::*; use crate::structures::*;
use crate::networking::{parse_tags};
#[test] #[test]
fn test_tag_new() { fn test_tag_new() {
@ -11,25 +11,38 @@ mod tests {
#[test] #[test]
fn test_tag_from_string() { fn test_tag_from_string() {
assert_eq!(Tag::from_string("#test".to_string()), Tag('#', "test".to_string())); assert_eq!(
Tag::from_string("#test".to_string()),
Tag('#', "test".to_string())
);
} }
#[test] #[test]
fn test_tag_to_string() { fn test_tag_to_string() {
assert_eq!(Tag('#', "test".to_string()).to_string(), "#test".to_string()); assert_eq!(
Tag('#', "test".to_string()).to_string(),
"#test".to_string()
);
} }
#[test] #[test]
fn test_shortcode_conversion() { fn test_shortcode_conversion() {
assert_eq!(construct_shortcode("Test SHORtcode".to_string()), "test-shortcode".to_string()); assert_eq!(
construct_shortcode("Test SHORtcode".to_string()),
"test-shortcode".to_string()
);
} }
#[test] #[test]
fn test_parse_tags() { fn test_parse_tags() {
assert_eq!(parse_tags("one,TWO ,tHRee, #four".to_string()), vec![ assert_eq!(
Tag('#',"one".to_string()), parse_tags("one,TWO ,tHRee, #four".to_string()),
Tag('#',"two".to_string()), vec![
Tag('#',"three".to_string()), Tag('#', "one".to_string()),
Tag('#',"four".to_string())]); Tag('#', "two".to_string()),
Tag('#', "three".to_string()),
Tag('#', "four".to_string())
]
);
} }
} }