Add an error management in db module
[recipes.git] / backend / src / main.rs
1 use std::io::prelude::*;
2 use std::{fs::File, env::args};
3
4 use actix_files as fs;
5 use actix_web::{get, web, Responder, middleware, App, HttpServer, HttpResponse, HttpRequest, web::Query};
6
7 use askama::Template;
8 use listenfd::ListenFd;
9 use ron::de::from_reader;
10 use serde::Deserialize;
11
12 use itertools::Itertools;
13
14 mod consts;
15 mod db;
16
17 #[derive(Template)]
18 #[template(path = "home.html")]
19 struct HomeTemplate {
20 recipes: Vec<db::Recipe>
21 }
22
23 #[derive(Template)]
24 #[template(path = "view_recipe.html")]
25 struct ViewRecipeTemplate {
26 recipes: Vec<db::Recipe>,
27 current_recipe: db::Recipe
28 }
29
30 #[derive(Deserialize)]
31 pub struct Request {
32 m: Option<String>
33 }
34
35 #[get("/")]
36 async fn home_page(req: HttpRequest) -> impl Responder {
37 HomeTemplate { recipes: vec![ db::Recipe { title: String::from("Saumon en croûte feuilletée"), id: 1 }, db::Recipe { title: String::from("Croissant au jambon"), id: 2 } ] }
38 }
39
40 #[get("/recipe/view/{id}")]
41 async fn view_page(req: HttpRequest, path: web::Path<(i32,)>) -> impl Responder {
42 ViewRecipeTemplate { recipes: vec![ db::Recipe { title: String::from("Saumon en croûte feuilletée"), id: 1 }, db::Recipe { title: String::from("Croissant au jambon"), id: 2 } ], current_recipe: db::Recipe { title: String::from("Saumon en croûte feuilletée"), id: 1 } }
43 }
44
45 #[derive(Debug, Deserialize)]
46 struct Config {
47 port: u16
48 }
49
50 fn get_exe_name() -> String {
51 let first_arg = std::env::args().nth(0).unwrap();
52 let sep: &[_] = &['\\', '/'];
53 first_arg[first_arg.rfind(sep).unwrap()+1..].to_string()
54 }
55
56 #[actix_rt::main]
57 async fn main() -> std::io::Result<()> {
58 if process_args() { return Ok(()) }
59
60 println!("Starting Recipes as web server...");
61
62 let config: Config = {
63 let f = File::open(consts::FILE_CONF).unwrap_or_else(|_| panic!("Failed to open configuration file {}", consts::FILE_CONF));
64 match from_reader(f) {
65 Ok(c) => c,
66 Err(e) => panic!("Failed to load config: {}", e)
67 }
68 };
69
70 println!("Configuration: {:?}", config);
71
72 // let database_connection = db::create_or_update();
73
74 std::env::set_var("RUST_LOG", "actix_web=info");
75
76 let mut listenfd = ListenFd::from_env();
77 let mut server =
78 HttpServer::new(
79 || {
80 App::new()
81 .wrap(middleware::Compress::default())
82 .service(home_page)
83 .service(view_page)
84 .service(fs::Files::new("/static", "static").show_files_listing())
85 }
86 );
87
88 server =
89 if let Some(l) = listenfd.take_tcp_listener(0).unwrap() {
90 server.listen(l).unwrap()
91 } else {
92 server.bind(&format!("0.0.0.0:{}", config.port)).unwrap()
93 };
94
95 server.run().await
96 }
97
98 fn process_args() -> bool {
99 fn print_usage() {
100 println!("Usage:");
101 println!(" {} [--help] [--test]", get_exe_name());
102 }
103
104 let args: Vec<String> = args().collect();
105
106 if args.iter().any(|arg| arg == "--help") {
107 print_usage();
108 return true
109 } else if args.iter().any(|arg| arg == "--test") {
110 match db::Connection::new() {
111 Ok(_) => (),
112 Err(error) => println!("Error: {:?}", error)
113 }
114 return true
115 }
116
117 false
118 }