From e91dae86cfb97cd872d69ad7285cf205be84ab35 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 15:11:12 +0200 Subject: [PATCH 1/9] feat(ai): cargo init with Makefile for all rules link with main Makefiles --- .gitignore | 3 +++ Makefile | 8 ++++---- ai/Cargo.toml | 8 ++++++++ ai/Makefile | 30 ++++++++++++++++++++++++++++++ ai/src/main.rs | 10 ++++++++++ 5 files changed, 55 insertions(+), 4 deletions(-) create mode 100644 ai/Cargo.toml create mode 100644 ai/Makefile create mode 100644 ai/src/main.rs diff --git a/.gitignore b/.gitignore index c64b6369..441e3d5d 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ zappy_ai zappy_gui *.o + +Cargo.lock +target/ \ No newline at end of file diff --git a/Makefile b/Makefile index fff44fc0..0524a67a 100644 --- a/Makefile +++ b/Makefile @@ -5,7 +5,7 @@ ## Makefile ## -all: gui server +all: gui server ai gui: @make -C gui @@ -18,17 +18,17 @@ server: clean: @make clean -C gui - # @make clean -C ai + @make clean -C ai @make clean -C server fclean: @make fclean -C gui - # @make fclean -C ai + @make fclean -C ai @make fclean -C server tests_run: @make tests_run -C gui - # @make tests_run -C ai + @make tests_run -C ai @make tests_run -C server re: fclean all diff --git a/ai/Cargo.toml b/ai/Cargo.toml new file mode 100644 index 00000000..6e865ffa --- /dev/null +++ b/ai/Cargo.toml @@ -0,0 +1,8 @@ +[package] +name = "ai" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] diff --git a/ai/Makefile b/ai/Makefile new file mode 100644 index 00000000..7cc2f3d4 --- /dev/null +++ b/ai/Makefile @@ -0,0 +1,30 @@ +## +## EPITECH PROJECT, 2024 +## Zappy +## File description: +## Makefile +## + +NAME = ../zappy_ai + +BIN = ai + +SRC = src/main.rs + +all: $(NAME) + +$(NAME): $(SRC) + cargo build --release --offline && cp ./target/release/$(BIN) $(NAME) + +clean: + cargo clean + +fclean: clean + rm -f $(NAME) + +tests_run: + cargo test --coverage + +re: fclean all + +.PHONY: all re clean fclean tests_run diff --git a/ai/src/main.rs b/ai/src/main.rs new file mode 100644 index 00000000..6a2c4c87 --- /dev/null +++ b/ai/src/main.rs @@ -0,0 +1,10 @@ +// +// EPITECH PROJECT, 2024 +// Zappy +// File description: +// main +// + +fn main() { + println!("Hello, world!"); +} From e22453beeb6acae539a5457cc6c5521782c6e835 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 16:16:37 +0200 Subject: [PATCH 2/9] feat(ai): start env::arg_os() for iterating arguments --- ai/src/main.rs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/ai/src/main.rs b/ai/src/main.rs index 6a2c4c87..23885fc4 100644 --- a/ai/src/main.rs +++ b/ai/src/main.rs @@ -5,6 +5,16 @@ // main // +use std::{env, process}; + fn main() { - println!("Hello, world!"); + let mut args = env::args_os(); + args.next(); + + if let Some(flag) = args.next() { + if flag.into_string().is_ok() { + } else { + eprintln!("Argument") + } + } } From 180c9dbdd6df5ecbc251f05791020658eb0714a3 Mon Sep 17 00:00:00 2001 From: Alexandre VIGOUREUX Date: Mon, 20 May 2024 18:06:28 +0200 Subject: [PATCH 3/9] feat(ai): args recovery for port (-p) --- ai/src/flags.rs | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ ai/src/main.rs | 14 ++++------- 2 files changed, 67 insertions(+), 9 deletions(-) create mode 100644 ai/src/flags.rs diff --git a/ai/src/flags.rs b/ai/src/flags.rs new file mode 100644 index 00000000..9292ddf9 --- /dev/null +++ b/ai/src/flags.rs @@ -0,0 +1,62 @@ +use std::env::{ArgsOs, args_os}; + +static LOCALHOST: &str = "127.0.0.1"; + +pub struct Flags { + pub port: Option, + pub name: Option, + pub machine: String, +} + +impl Flags { + fn new() -> Flags { + Flags { port: None, name: None, machine: String::from(LOCALHOST) } + } + + fn set_port(&mut self, port: usize) { + self.port = Some(port) + } + fn set_name(&mut self, name: String) { + self.name = Some(name) + } + fn set_machine(&mut self, machine: String) { + self.machine = machine + } +} + +fn get_port_from_args<'a>( + args: &'a mut ArgsOs, + flags_struct: &'a mut Flags +) -> Result<&'a mut Flags, String> { + args.next().map(|arg| { + match arg.into_string() { + Ok(arg) => arg.as_str().parse::() + .map(|port| { + flags_struct.set_port(port); + Ok(flags_struct) + }) + .expect("Failed to parse port"), + Err(_) => Err(String::from("ArgsOs error, not a string")) + } + }).expect("error") +} + +pub fn get_flags() -> Result { + let mut flags_struct = Flags::new(); + let mut args = args_os(); + + args.next(); + while let Some(flag) = args.next() { + if let Ok(flag) = flag.into_string() { + match flag.as_str() { + "-p" => get_port_from_args(&mut args, &mut flags_struct), + //"-n" => println!("-n"), + //"-h" => println!("-h"), + var_str => Err(String::from("Unknown flag of value ") + var_str), + }; + } else { + return Err(String::from("Error")) + } + } + Ok(flags_struct) +} diff --git a/ai/src/main.rs b/ai/src/main.rs index 23885fc4..0bab2836 100644 --- a/ai/src/main.rs +++ b/ai/src/main.rs @@ -5,16 +5,12 @@ // main // -use std::{env, process}; +mod flags; fn main() { - let mut args = env::args_os(); - args.next(); - - if let Some(flag) = args.next() { - if flag.into_string().is_ok() { - } else { - eprintln!("Argument") - } + let tmp = flags::get_flags(); + match tmp { + Ok(res) => println!("{:?}", res.port), + Err(e) => println!("{}", e) } } From 8ae25bd54e272d0b5cb3fe39694c0d92fed1fdbc Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 19:13:59 +0200 Subject: [PATCH 4/9] refactor(ai): parsing arguments for all flags --- ai/src/flags.rs | 108 +++++++++++++++++++++++++++++++++++------------- ai/src/main.rs | 4 +- 2 files changed, 82 insertions(+), 30 deletions(-) diff --git a/ai/src/flags.rs b/ai/src/flags.rs index 9292ddf9..d07d042b 100644 --- a/ai/src/flags.rs +++ b/ai/src/flags.rs @@ -1,7 +1,17 @@ -use std::env::{ArgsOs, args_os}; +// +// EPITECH PROJECT, 2024 +// Zappy +// File description: +// flags +// + +use std::env::{args_os, ArgsOs}; +use std::ffi::OsString; +use std::str::FromStr; static LOCALHOST: &str = "127.0.0.1"; +#[derive(Debug)] pub struct Flags { pub port: Option, pub name: Option, @@ -10,7 +20,11 @@ pub struct Flags { impl Flags { fn new() -> Flags { - Flags { port: None, name: None, machine: String::from(LOCALHOST) } + Flags { + port: None, + name: None, + machine: String::from(LOCALHOST), + } } fn set_port(&mut self, port: usize) { @@ -24,39 +38,77 @@ impl Flags { } } -fn get_port_from_args<'a>( - args: &'a mut ArgsOs, - flags_struct: &'a mut Flags -) -> Result<&'a mut Flags, String> { - args.next().map(|arg| { - match arg.into_string() { - Ok(arg) => arg.as_str().parse::() - .map(|port| { - flags_struct.set_port(port); - Ok(flags_struct) - }) - .expect("Failed to parse port"), - Err(_) => Err(String::from("ArgsOs error, not a string")) - } - }).expect("error") +impl std::fmt::Display for Flags { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + write!( + f, + "Machine: {}, Port: {}, Name: {}", + self.machine, + self.port + .map_or_else(|| "None".to_string(), |p| p.to_string()), + self.name.clone().unwrap_or_else(|| "None".to_string()) + ) + } +} + +fn parse_arg(arg_type: &str, arg: Option) -> Result { + arg.ok_or_else(|| String::from(format!("Flag `{}` argument is missing.", arg_type))) + .and_then(|arg| { + arg.into_string() + .map_err(|_| String::from("Invalid UTF-8 Format.")) + }) + .and_then(|arg| { + arg.parse::() + .map_err(|_| String::from(format!("Failed to parse argument for {}.", arg_type))) + }) +} + +fn get_port_from_args( + arg_type: &str, + args: &mut ArgsOs, + flags_struct: &mut Flags, +) -> Result<(), String> { + let port: usize = parse_arg(arg_type, args.next())?; + flags_struct.set_port(port); + Ok(()) +} + +fn get_name_from_args( + arg_type: &str, + args: &mut ArgsOs, + flags_struct: &mut Flags, +) -> Result<(), String> { + let name: String = parse_arg(arg_type, args.next())?; + flags_struct.set_name(name); + Ok(()) +} + +fn get_machine_from_args( + arg_type: &str, + args: &mut ArgsOs, + flags_struct: &mut Flags, +) -> Result<(), String> { + let machine: String = parse_arg(arg_type, args.next())?; + flags_struct.set_machine(machine); + Ok(()) } pub fn get_flags() -> Result { let mut flags_struct = Flags::new(); let mut args = args_os(); - args.next(); + while let Some(flag) = args.next() { - if let Ok(flag) = flag.into_string() { - match flag.as_str() { - "-p" => get_port_from_args(&mut args, &mut flags_struct), - //"-n" => println!("-n"), - //"-h" => println!("-h"), - var_str => Err(String::from("Unknown flag of value ") + var_str), - }; - } else { - return Err(String::from("Error")) - } + match flag + .into_string() + .map_err(|_| String::from("Invalid UTF-8 Format."))? + .as_str() + { + "-p" => get_port_from_args("port", &mut args, &mut flags_struct)?, + "-n" => get_name_from_args("name", &mut args, &mut flags_struct)?, + "-h" => get_machine_from_args("machine", &mut args, &mut flags_struct)?, + any => return Err(String::from(format!("Unknown flag: {}.", any))), + }; } Ok(flags_struct) } diff --git a/ai/src/main.rs b/ai/src/main.rs index 0bab2836..f87db515 100644 --- a/ai/src/main.rs +++ b/ai/src/main.rs @@ -10,7 +10,7 @@ mod flags; fn main() { let tmp = flags::get_flags(); match tmp { - Ok(res) => println!("{:?}", res.port), - Err(e) => println!("{}", e) + Ok(res) => println!("{}", res), + Err(e) => println!("{}", e), } } From deddec03fa936c011be6dcfac65e74e0bd715dab Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 19:29:38 +0200 Subject: [PATCH 5/9] feat(ai): check if all necessary fields are parsed check if values are equal to NONE --- ai/src/flags.rs | 37 ++++++++++++++++++++++++++++++++----- ai/src/main.rs | 16 ++++++++++++---- 2 files changed, 44 insertions(+), 9 deletions(-) diff --git a/ai/src/flags.rs b/ai/src/flags.rs index d07d042b..5141fdb9 100644 --- a/ai/src/flags.rs +++ b/ai/src/flags.rs @@ -13,11 +13,12 @@ static LOCALHOST: &str = "127.0.0.1"; #[derive(Debug)] pub struct Flags { - pub port: Option, - pub name: Option, - pub machine: String, + port: Option, + name: Option, + machine: String, } +#[allow(dead_code)] impl Flags { fn new() -> Flags { Flags { @@ -30,19 +31,30 @@ impl Flags { fn set_port(&mut self, port: usize) { self.port = Some(port) } + fn set_name(&mut self, name: String) { self.name = Some(name) } + fn set_machine(&mut self, machine: String) { self.machine = machine } + + pub fn is_port_none(&self) -> bool { + self.port.is_none() + } + + pub fn is_name_none(&self) -> bool { + self.name.is_none() + } + } impl std::fmt::Display for Flags { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, - "Machine: {}, Port: {}, Name: {}", + "Flags {{\n Machine: {},\n Port: {},\n Name: {}\n}};", self.machine, self.port .map_or_else(|| "None".to_string(), |p| p.to_string()), @@ -93,7 +105,7 @@ fn get_machine_from_args( Ok(()) } -pub fn get_flags() -> Result { +fn get_flags() -> Result { let mut flags_struct = Flags::new(); let mut args = args_os(); args.next(); @@ -112,3 +124,18 @@ pub fn get_flags() -> Result { } Ok(flags_struct) } + +pub fn check_flags() -> Result { + match get_flags() { + Ok(flags) => { + if flags.is_port_none() { + return Err(String::from("Port is not set.")) + } + if flags.is_name_none() { + return Err(String::from("Name is not set.")) + } + return Ok(flags); + } + Err(e) => Err(e) + } +} diff --git a/ai/src/main.rs b/ai/src/main.rs index f87db515..6a07804e 100644 --- a/ai/src/main.rs +++ b/ai/src/main.rs @@ -5,12 +5,20 @@ // main // +use std::process; + mod flags; +static ERROR_CODE: i32 = 84; + fn main() { - let tmp = flags::get_flags(); - match tmp { - Ok(res) => println!("{}", res), - Err(e) => println!("{}", e), + match flags::check_flags() { + Ok(res) => { + println!("{}", res) + }, + Err(e) => { + println!("Error: {}", e); + process::exit(ERROR_CODE) + } } } From 28462ea59b331339bc1710362c2c40dccae4106c Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 19:33:13 +0200 Subject: [PATCH 6/9] style(ai): cargo fmt + refactor String::from to format --- ai/src/flags.rs | 25 ++++++++++--------------- ai/src/main.rs | 4 +--- 2 files changed, 11 insertions(+), 18 deletions(-) diff --git a/ai/src/flags.rs b/ai/src/flags.rs index 5141fdb9..ab720b20 100644 --- a/ai/src/flags.rs +++ b/ai/src/flags.rs @@ -47,7 +47,6 @@ impl Flags { pub fn is_name_none(&self) -> bool { self.name.is_none() } - } impl std::fmt::Display for Flags { @@ -64,14 +63,14 @@ impl std::fmt::Display for Flags { } fn parse_arg(arg_type: &str, arg: Option) -> Result { - arg.ok_or_else(|| String::from(format!("Flag `{}` argument is missing.", arg_type))) + arg.ok_or_else(|| format!("Flag `{}` argument is missing.", arg_type)) .and_then(|arg| { arg.into_string() .map_err(|_| String::from("Invalid UTF-8 Format.")) }) .and_then(|arg| { arg.parse::() - .map_err(|_| String::from(format!("Failed to parse argument for {}.", arg_type))) + .map_err(|_| format!("Failed to parse argument for {}.", arg_type)) }) } @@ -119,23 +118,19 @@ fn get_flags() -> Result { "-p" => get_port_from_args("port", &mut args, &mut flags_struct)?, "-n" => get_name_from_args("name", &mut args, &mut flags_struct)?, "-h" => get_machine_from_args("machine", &mut args, &mut flags_struct)?, - any => return Err(String::from(format!("Unknown flag: {}.", any))), + any => return Err(format!("Unknown flag: {}.", any)), }; } Ok(flags_struct) } pub fn check_flags() -> Result { - match get_flags() { - Ok(flags) => { - if flags.is_port_none() { - return Err(String::from("Port is not set.")) - } - if flags.is_name_none() { - return Err(String::from("Name is not set.")) - } - return Ok(flags); - } - Err(e) => Err(e) + let flags = get_flags()?; + if flags.is_port_none() { + return Err(String::from("Port is not set.")); + } + if flags.is_name_none() { + return Err(String::from("Name is not set.")); } + Ok(flags) } diff --git a/ai/src/main.rs b/ai/src/main.rs index 6a07804e..55987504 100644 --- a/ai/src/main.rs +++ b/ai/src/main.rs @@ -13,9 +13,7 @@ static ERROR_CODE: i32 = 84; fn main() { match flags::check_flags() { - Ok(res) => { - println!("{}", res) - }, + Ok(res) => println!("{}", res), Err(e) => { println!("Error: {}", e); process::exit(ERROR_CODE) From 105df690307fde563ec5c6c61c6f99fb6bbe113b Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 19:42:31 +0200 Subject: [PATCH 7/9] feat(ai): add help flag to parsing of arguments for usage errors also bring usage --- ai/src/flags.rs | 18 +++++++++++++++++- ai/src/main.rs | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/ai/src/flags.rs b/ai/src/flags.rs index ab720b20..eed53c87 100644 --- a/ai/src/flags.rs +++ b/ai/src/flags.rs @@ -7,10 +7,13 @@ use std::env::{args_os, ArgsOs}; use std::ffi::OsString; +use std::process; use std::str::FromStr; static LOCALHOST: &str = "127.0.0.1"; +static SUCCESS_CODE: i32 = 0; + #[derive(Debug)] pub struct Flags { port: Option, @@ -105,8 +108,8 @@ fn get_machine_from_args( } fn get_flags() -> Result { - let mut flags_struct = Flags::new(); let mut args = args_os(); + let mut flags_struct = Flags::new(); args.next(); while let Some(flag) = args.next() { @@ -115,6 +118,10 @@ fn get_flags() -> Result { .map_err(|_| String::from("Invalid UTF-8 Format."))? .as_str() { + "-help" => { + usage(); + process::exit(SUCCESS_CODE); + } "-p" => get_port_from_args("port", &mut args, &mut flags_struct)?, "-n" => get_name_from_args("name", &mut args, &mut flags_struct)?, "-h" => get_machine_from_args("machine", &mut args, &mut flags_struct)?, @@ -134,3 +141,12 @@ pub fn check_flags() -> Result { } Ok(flags) } + +pub fn usage() { + println!( + "USAGE: ./zappy_ai -p port -n name -h machine + -p `port` port number + -n `name` name of the team + -h `machine` name of the machine; localhost by default" + ) +} diff --git a/ai/src/main.rs b/ai/src/main.rs index 55987504..4f55ee3f 100644 --- a/ai/src/main.rs +++ b/ai/src/main.rs @@ -16,6 +16,7 @@ fn main() { Ok(res) => println!("{}", res), Err(e) => { println!("Error: {}", e); + flags::usage(); process::exit(ERROR_CODE) } } From 4e67979e4c2974add1fc03d47b1422d54bd4c06d Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Mon, 20 May 2024 19:42:54 +0200 Subject: [PATCH 8/9] fix(build): make tests_run doesnt apply --coverage for cargo test --- ai/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ai/Makefile b/ai/Makefile index 7cc2f3d4..c500399e 100644 --- a/ai/Makefile +++ b/ai/Makefile @@ -23,7 +23,7 @@ fclean: clean rm -f $(NAME) tests_run: - cargo test --coverage + cargo test re: fclean all From 2a363d9c7e2fb11ce848d82fc49fd6b8675cdfa8 Mon Sep 17 00:00:00 2001 From: Lou Onezime Date: Tue, 21 May 2024 19:05:41 +0200 Subject: [PATCH 9/9] refactor(ai): flag implementation uses default instead of new --- ai/src/flags.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/ai/src/flags.rs b/ai/src/flags.rs index eed53c87..5bffe736 100644 --- a/ai/src/flags.rs +++ b/ai/src/flags.rs @@ -5,11 +5,16 @@ // flags // +#![allow(dead_code)] + use std::env::{args_os, ArgsOs}; -use std::ffi::OsString; use std::process; + +use std::ffi::OsString; use std::str::FromStr; +use std::fmt::Display; + static LOCALHOST: &str = "127.0.0.1"; static SUCCESS_CODE: i32 = 0; @@ -21,16 +26,7 @@ pub struct Flags { machine: String, } -#[allow(dead_code)] impl Flags { - fn new() -> Flags { - Flags { - port: None, - name: None, - machine: String::from(LOCALHOST), - } - } - fn set_port(&mut self, port: usize) { self.port = Some(port) } @@ -52,7 +48,17 @@ impl Flags { } } -impl std::fmt::Display for Flags { +impl Default for Flags { + fn default() -> Flags { + Flags { + port: None, + name: None, + machine: String::from(LOCALHOST), + } + } +} + +impl Display for Flags { fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { write!( f, @@ -109,7 +115,7 @@ fn get_machine_from_args( fn get_flags() -> Result { let mut args = args_os(); - let mut flags_struct = Flags::new(); + let mut flags_struct = Flags::default(); args.next(); while let Some(flag) = args.next() {