red/src/main.rs

153 lines
4.2 KiB
Rust
Raw Normal View History

2023-04-10 17:43:12 +00:00
mod buffer;
mod enums;
2023-04-10 17:43:12 +00:00
pub use self::buffer::Buffer;
2023-04-23 01:31:12 +00:00
pub use self::enums::{parse_address, parse_command, Address, Command};
2023-04-10 17:43:12 +00:00
2023-04-23 01:31:12 +00:00
use nom::bytes::complete::take_while;
2023-04-10 17:43:12 +00:00
use nom::character::complete::one_of;
use nom::error::ErrorKind;
2023-04-23 01:31:12 +00:00
use nom::sequence::Tuple;
use nom::Err::Error;
2023-04-23 01:31:12 +00:00
use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;
2023-04-10 17:43:12 +00:00
2023-04-23 01:31:12 +00:00
const FILE: &str = "test";
2023-04-10 17:43:12 +00:00
2023-04-23 00:59:28 +00:00
#[derive(PartialEq)]
enum Exit {
Continue,
HasBeenModified,
Quit,
}
2023-04-10 17:43:12 +00:00
// TODO juste $ pour l'instant dans l'adresse
// TODO faire les commandes mais juste p pour l'instant
// TODO faire un système de retour d'erreur pour afficher ? et l'erreur si l'utilisateur le demande
// (cad les fonctions pour parser retournent un Err et on peut parser ce Err pour voir le type de
// l'erreur, idem pour les fonctions d'exécutiosn ?)
2023-04-10 17:43:12 +00:00
/*
fn read_address(input: &str) -> Result<&str, Address> {
2023-04-23 01:31:12 +00:00
2023-04-10 17:43:12 +00:00
}
*/
/*
* Le char doit être une commande valide.
*/
fn check_address(c: char) -> bool {
2023-04-23 01:31:12 +00:00
c.is_ascii_digit() || c == '$' || c == ' ' || c == '.'
2023-04-10 17:43:12 +00:00
}
fn check_address_complete(c: char) -> bool {
2023-04-15 23:03:46 +00:00
check_address(c) || c == ',' || c == ';'
2023-04-10 17:43:12 +00:00
}
fn read_user_input() -> Vec<String> {
let mut buffer: Vec<String> = Vec::new();
let mut buffer_input = String::new();
while buffer_input != "." {
buffer_input.clear();
match io::stdin().read_line(&mut buffer_input) {
Ok(_) => {
buffer_input.pop();
if buffer_input != "." {
buffer.push(buffer_input.clone());
}
}
Err(e) => panic!("{}", e),
}
}
buffer
}
2023-04-23 00:59:28 +00:00
fn execute_command(buffer: &mut Buffer, c: Command) -> Exit {
let mut ret = Exit::Continue;
2023-04-10 17:43:12 +00:00
match c {
Command::Append(a) => buffer.append(a, read_user_input()),
Command::Insert(a) => buffer.insert(a, read_user_input()),
2023-04-23 17:17:13 +00:00
Command::Delete(a) => buffer.delete(a),
Command::Print(a) => buffer.print(a, false),
Command::Number(a) => buffer.print(a, true),
2023-04-23 01:31:12 +00:00
Command::Quit(q) => {
if buffer.is_modified() {
if q {
ret = Exit::Quit;
} else {
ret = Exit::HasBeenModified;
}
2023-04-23 00:59:28 +00:00
} else {
2023-04-23 01:31:12 +00:00
ret = Exit::Quit;
2023-04-23 00:59:28 +00:00
}
2023-04-23 01:31:12 +00:00
}
2023-04-23 09:48:54 +00:00
Command::Write(a) => {
buffer.save(a);
2023-04-23 01:01:37 +00:00
ret = Exit::Continue;
2023-04-23 01:31:12 +00:00
}
_ => (),
2023-04-10 17:43:12 +00:00
}
ret
2023-04-10 17:43:12 +00:00
}
fn parse_line(input: &str) -> Result<Command, String> {
let address = take_while(check_address_complete);
2023-04-23 17:17:13 +00:00
let command = one_of::<_, _, (&str, ErrorKind)>("aidpnqQw");
2023-04-10 17:43:12 +00:00
//if let Ok((input, (a, c))) = alt(address, command).parse(input) {
let tmp = (address, command).parse(input);
2023-04-23 01:31:12 +00:00
if let Ok((_input, (a, c))) = tmp {
2023-04-10 17:43:12 +00:00
let addr = parse_address(a);
2023-04-22 13:12:27 +00:00
parse_command(c, addr)
2023-04-23 01:31:12 +00:00
} else if let Err(Error((_, _))) = tmp {
2023-04-22 13:12:27 +00:00
Err(String::from("Erreur de parsing"))
2023-04-10 17:43:12 +00:00
} else {
2023-04-22 13:12:27 +00:00
Err(String::from("Grosse erreur"))
2023-04-10 17:43:12 +00:00
}
}
fn main() {
2023-04-23 01:31:12 +00:00
let buffer: Vec<Result<String, io::Error>> = if let Ok(f) = File::open(FILE) {
2023-04-10 17:43:12 +00:00
let buff = BufReader::new(f);
buff.lines().collect()
} else {
panic!("Le fichier n'existe pas.");
};
2023-04-23 01:01:37 +00:00
let mut buffer_struct = Buffer::new(FILE, buffer);
2023-04-10 17:43:12 +00:00
println!("fichier lu !");
2023-04-23 00:59:28 +00:00
let mut pred = Exit::Continue;
2023-04-23 00:59:28 +00:00
while pred != Exit::Quit {
let mut input = String::new();
match io::stdin().read_line(&mut input) {
2023-04-23 01:31:12 +00:00
Ok(_) => {
2023-04-22 13:12:27 +00:00
let result_parse = parse_line(&input);
if let Ok(c) = result_parse {
2023-04-23 00:59:28 +00:00
pred = match execute_command(&mut buffer_struct, c) {
2023-04-23 01:31:12 +00:00
Exit::HasBeenModified => {
if pred == Exit::HasBeenModified {
Exit::Quit
} else {
Exit::HasBeenModified
}
}
2023-04-23 00:59:28 +00:00
exit => exit,
}
2023-04-22 13:12:27 +00:00
} else if let Err(e) = result_parse {
println!("?");
println!("{}", e);
2023-04-23 00:59:28 +00:00
pred = Exit::Continue;
}
2023-04-23 01:31:12 +00:00
}
2023-04-23 00:59:28 +00:00
Err(e) => panic!("{}", e),
}
2023-04-10 17:43:12 +00:00
}
}