From 6873a7136306af626db1bb96bd3a4991e632e721 Mon Sep 17 00:00:00 2001 From: Yohan Boujon Date: Fri, 2 May 2025 10:54:35 +0200 Subject: [PATCH] Added basic server and logger in Rust. --- backend/.gitignore | 3 +- backend/Cargo.toml | 10 +++++ backend/README.md | 0 backend/go.mod | 3 -- backend/main.go | 14 ------- backend/server/pictures.go | 16 -------- backend/server/server.go | 44 --------------------- backend/src/log.rs | 80 ++++++++++++++++++++++++++++++++++++++ backend/src/main.rs | 21 ++++++++++ backend/util/logger.go | 59 ---------------------------- backend/util/util.go | 18 --------- 11 files changed, 113 insertions(+), 155 deletions(-) create mode 100644 backend/Cargo.toml delete mode 100644 backend/README.md delete mode 100644 backend/go.mod delete mode 100644 backend/main.go delete mode 100644 backend/server/pictures.go delete mode 100644 backend/server/server.go create mode 100644 backend/src/log.rs create mode 100644 backend/src/main.rs delete mode 100644 backend/util/logger.go delete mode 100644 backend/util/util.go diff --git a/backend/.gitignore b/backend/.gitignore index 2eea525..d79b720 100644 --- a/backend/.gitignore +++ b/backend/.gitignore @@ -1 +1,2 @@ -.env \ No newline at end of file +**/target/** +Cargo.lock \ No newline at end of file diff --git a/backend/Cargo.toml b/backend/Cargo.toml new file mode 100644 index 0000000..997ea59 --- /dev/null +++ b/backend/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "backend" +version = "0.1.0" +edition = "2024" + +[dependencies] +actix-web = "4.10.2" +chrono = "0.4.41" +serde = { version = "1.0.219", features = ["derive"]} +serde_json = "1.0.140" diff --git a/backend/README.md b/backend/README.md deleted file mode 100644 index e69de29..0000000 diff --git a/backend/go.mod b/backend/go.mod deleted file mode 100644 index 9be7739..0000000 --- a/backend/go.mod +++ /dev/null @@ -1,3 +0,0 @@ -module backend - -go 1.24.2 diff --git a/backend/main.go b/backend/main.go deleted file mode 100644 index f851159..0000000 --- a/backend/main.go +++ /dev/null @@ -1,14 +0,0 @@ -package main - -import ( - "backend/server" - "backend/util" -) - -func main() { - // Checking arguments - util.SetLevel(util.NOLOG) - - // Rest API start on port - server.Start(8085) -} diff --git a/backend/server/pictures.go b/backend/server/pictures.go deleted file mode 100644 index 6611ea1..0000000 --- a/backend/server/pictures.go +++ /dev/null @@ -1,16 +0,0 @@ -package server - -import ( - "backend/util" - "net/http" -) - -func getphoto(w http.ResponseWriter, r *http.Request) { - idStr := r.URL.Query().Get("id") - if idStr == "" { - util.Logformat(util.ERROR, "%s: Missing 'id' parameter.", util.GetFunctionName()) - http.Error(w, "Missing or invalid parameters : id", http.StatusBadRequest) - } else { - sendResponse(w, 0) - } -} diff --git a/backend/server/server.go b/backend/server/server.go deleted file mode 100644 index 9613c74..0000000 --- a/backend/server/server.go +++ /dev/null @@ -1,44 +0,0 @@ -package server - -import ( - "backend/util" - "encoding/json" - "net/http" - "strconv" -) - -func Start(port int64) { - // Creating endpoints - http.HandleFunc("/getphoto", wrapHeader(getphoto)) - - util.Logformat(util.INFO, "Starting server on port %d...\n", port) - if err := http.ListenAndServe(":"+strconv.FormatInt(port, 10), nil); err != nil { - util.Logformat(util.ERROR, "Could not start server (%s)\n", err.Error()) - panic(err) - } -} - -func sendResponse(w http.ResponseWriter, r any) { - w.Header().Set("Content-Type", "application/json") - if err := json.NewEncoder(w).Encode(r); err != nil { - util.Logformat(util.ERROR, "%s\n", err.Error()) - http.Error(w, err.Error(), http.StatusInternalServerError) - return - } -} - -// Not sure about that, might change it later... (added by Lemonochrme on 'yoboujon/automatic-management') -func wrapHeader(next http.HandlerFunc) http.HandlerFunc { - return func(w http.ResponseWriter, r *http.Request) { - w.Header().Set("Access-Control-Allow-Origin", "*") - w.Header().Set("Access-Control-Allow-Methods", "GET") - w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Authorization") - - if r.Method == http.MethodOptions { - w.WriteHeader(http.StatusOK) - return - } - - next(w, r) - } -} diff --git a/backend/src/log.rs b/backend/src/log.rs new file mode 100644 index 0000000..5e59a64 --- /dev/null +++ b/backend/src/log.rs @@ -0,0 +1,80 @@ +use std::collections::HashMap; +use std::fmt::Arguments; +use chrono::{Datelike, Local, Timelike}; +use std::io::{self, Write}; + +#[derive(Eq, PartialEq, Hash)] +pub enum LogLevel { + NOLOG, + INFO, + CORRECT, + WARNING, + ERROR, +} + +#[allow(dead_code)] +pub enum ColorFormat { + BLUE, + GREEN, + YELLOW, + RED, + LIGHTRED, + WHITE, + RESET, +} + +impl ColorFormat { + fn as_str(&self) -> &'static str { + match self { + ColorFormat::BLUE => "\x1b[34m", + ColorFormat::GREEN => "\x1b[32m", + ColorFormat::YELLOW => "\x1b[33m", + ColorFormat::RED => "\x1b[31m", + ColorFormat::LIGHTRED => "\x1b[91m", + ColorFormat::WHITE => "\x1b[97m", + ColorFormat::RESET => "\x1b[0m", + } + } +} + +fn get_color_print() -> HashMap { + let mut map = HashMap::new(); + map.insert(LogLevel::NOLOG, ""); + map.insert(LogLevel::INFO, concat!("\x1b[34m","[INFO]","\x1b[0m")); + map.insert(LogLevel::CORRECT, concat!("\x1b[32m","[OK ]", "\x1b[92m")); + map.insert(LogLevel::WARNING, concat!("\x1b[33m", "[WARN]", "\x1b[93m")); + map.insert(LogLevel::ERROR, concat!("\x1b[31m", "[ERR ]", "\x1b[91m")); + map +} + +pub fn log_format(level: LogLevel, args: Arguments) { + let color_map = get_color_print(); + let header = color_map.get(&level).copied().unwrap_or(""); + let message = format!("{}", args); + let now = Local::now(); + let time = format!( + "[{:02}/{:02}/{} {:02}:{:02}:{:02}]", + now.day(), + now.month(), + now.year(), + now.hour(), + now.minute(), + now.second() + ); + + if level == LogLevel::NOLOG { + println!("{}\t\t{}", time, message); + } else if level != LogLevel::INFO { + println!("{}{}\t{}{}", header, time, message, ColorFormat::RESET.as_str()); + } else { + println!("{}{}\t{}", header, time, message); + } + io::stdout().flush().unwrap(); +} + +#[macro_export] +macro_rules! logf { + ($level:expr, $fmt:expr $(, $arg:expr)* $(,)?) => { + log::log_format($level, format_args!($fmt $(, $arg)*)) + }; +} \ No newline at end of file diff --git a/backend/src/main.rs b/backend/src/main.rs new file mode 100644 index 0000000..1d200a2 --- /dev/null +++ b/backend/src/main.rs @@ -0,0 +1,21 @@ +use actix_web::{web, App, HttpResponse, HttpServer, Responder}; + +mod log; +use log::LogLevel; + +async fn hello() -> impl Responder { + HttpResponse::Ok().body("Hello world") +} + +#[actix_web::main] +async fn main() -> std::io::Result<()> { + logf!(LogLevel::INFO, "This is an info log."); + logf!(LogLevel::CORRECT, "This is a correct log."); + logf!(LogLevel::ERROR, "This is an error log."); + logf!(LogLevel::WARNING, "This is a warning log."); + logf!(LogLevel::NOLOG, "This is no log."); + HttpServer::new(|| App::new().route("/hello", web::get().to(hello))) + .bind("127.0.0.1:8080")? + .run() + .await +} diff --git a/backend/util/logger.go b/backend/util/logger.go deleted file mode 100644 index 0cb096c..0000000 --- a/backend/util/logger.go +++ /dev/null @@ -1,59 +0,0 @@ -package util - -import ( - "fmt" - "time" -) - -type colorFormat string -type LogLevel int - -const ( - BLUE colorFormat = "\033[34m" - GREEN colorFormat = "\033[32m" - YELLOW colorFormat = "\033[33m" - RED colorFormat = "\033[31m" - LIGHT_RED colorFormat = "\033[91m" - WHITE colorFormat = "\033[97m" - RESET colorFormat = "\033[0m" -) - -const ( - NOLOG LogLevel = iota - INFO - CORRECT - WARNING - ERROR -) - -var colorPrint = map[LogLevel]colorFormat{ - NOLOG: "", - INFO: BLUE + "[INFO]" + RESET, - CORRECT: GREEN, - WARNING: YELLOW + "[WARN]", - ERROR: RED + "[ERR.]" + LIGHT_RED, -} - -var minimumlog = NOLOG - -func Logformat(level LogLevel, format string, args ...interface{}) { - if level < minimumlog { - return - } - - header := colorPrint[level] - message := fmt.Sprintf(format, args...) - currentTime := time.Now() - time := fmt.Sprintf("[%02d/%02d/%d %02d:%02d:%02d]", currentTime.Day(), currentTime.Month(), currentTime.Year(), currentTime.Hour(), currentTime.Minute(), currentTime.Second()) - if level == NOLOG { - fmt.Printf("%s\t\t%s", time, message) - } else if level != INFO { - fmt.Printf("%s%s\t%s%s", header, time, message, RESET) - } else { - fmt.Printf("%s%s\t%s", header, time, message) - } -} - -func SetLevel(level LogLevel) { - minimumlog = level -} diff --git a/backend/util/util.go b/backend/util/util.go deleted file mode 100644 index 488c318..0000000 --- a/backend/util/util.go +++ /dev/null @@ -1,18 +0,0 @@ -package util - -import ( - "net/http" - "runtime" - "strings" -) - -func GetFunctionName() string { - pc, _, _, _ := runtime.Caller(1) - f := runtime.FuncForPC(pc) - return strings.Split(strings.Split(f.Name(), "/")[1], ".")[1] -} - -func HasSubURI(r *http.Request) (bool, string) { - url := strings.Split(r.URL.Path, "/") - return (len(url[2]) > 0), url[2] -}