red/src/enums.rs
2023-04-23 19:17:13 +02:00

197 lines
4.1 KiB
Rust

use std::num::ParseIntError;
use std::str::FromStr;
#[derive(Debug)]
pub enum Address {
Actual,
// utile pour write qui considère une adresse nulle comme l'ensemble du
// fichier par défaut
Empty,
Last,
Line(usize),
FromStartTo(usize),
FromToEnd(usize), // pas sur ?
FromTo(usize, usize),
FromActTo(usize),
FromActToEnd,
All,
Null,
}
impl Address {
pub fn is_multi_line(&self) -> bool {
!matches!(
self,
Address::Null | Address::Actual | Address::Last | Address::Line(_) | Address::Empty
)
}
}
pub fn parse_address(addr: &str) -> Address {
let mut tmp = String::from(addr);
tmp.retain(|c| c != ' ');
let addr = tmp.as_str();
if addr.is_empty() {
Address::Empty
} else if addr.contains(',') || addr.contains(';') {
parse_multi_addr(addr)
} else if let Ok(l) = usize::from_str(addr) {
Address::Line(l)
} else {
match addr {
"." => Address::Actual,
"$" => Address::Last,
_ => Address::Null,
}
}
}
fn parse_multi_addr(addr: &str) -> Address {
// garde con ou pas ?
let is_comma = addr.contains(',');
let tmp: Vec<&str> = if is_comma {
addr.split(',').collect()
} else {
addr.split(';').collect()
};
if tmp.len() != 2 {
Address::Null
} else {
let start = usize::from_str(tmp[0]);
let end = usize::from_str(tmp[1]);
if let Ok(a) = start {
if let Ok(b) = end {
Address::FromTo(a, b)
} else {
Address::Line(a)
}
} else if is_comma {
parse_comma(end)
} else {
parse_semicolon(end)
}
}
}
fn parse_comma(end: Result<usize, ParseIntError>) -> Address {
if let Ok(a) = end {
Address::FromStartTo(a)
} else {
Address::All
}
}
fn parse_semicolon(end: Result<usize, ParseIntError>) -> Address {
if let Ok(a) = end {
Address::FromActTo(a)
} else {
Address::FromActToEnd
}
}
#[derive(Debug)]
pub enum Command {
// TODO
Append(Address),
Insert(Address),
// TODO
Change(Address),
// TODO
Delete(Address),
// bool pour check ou pas (e et E) TODO mettre le chemin vers le fichier
Edit(bool),
// TODO chemin vers fichier
File(),
// TODO
Help,
// TODO
SetHelp,
// TODO
Join(Address),
// TODO nom de la marque
Mark(Address),
// TODO
List(Address),
// TODO
Move(Address),
// TODO
Number(Address),
Print(Address),
// TODO
Prompt,
// bool pour check ou pas (q et Q)
Quit(bool),
// TODO
Read,
// TODO
Substitute,
// TODO
CopyLines,
// TODO
Undo,
// TODO nom de fichier
Write(Address),
// TODO
Line,
// TODO
ShellCommand,
// TODO
Null,
// TODO
Global,
// TODO
NonMatched,
}
/*
fn parse_without_addr(c: char) -> Command {
match c {
'q' => Command::Quit(false),
'Q' => Command::Quit(true),
_ => Command::Help,
}
}
*/
fn parse(c: char, addr: Address) -> Result<Command, String> {
match c {
'a' => {
if addr.is_multi_line() {
Err(String::from("Erreur d'adresse"))
} else {
Ok(Command::Append(addr))
}
}
'i' => {
if addr.is_multi_line() {
Err(String::from("Erreur d'adresse"))
} else {
Ok(Command::Insert(addr))
}
}
'd' => Ok(Command::Delete(addr)),
'p' => Ok(Command::Print(addr)),
'n' => Ok(Command::Number(addr)),
'q' => Ok(Command::Quit(false)),
'Q' => Ok(Command::Quit(true)),
'w' => Ok(Command::Write(addr)),
_ => Ok(Command::Help),
}
}
pub fn parse_command(c: char, addr: Address) -> Result<Command, String> {
parse(c, addr)
/*
if let Some(a) = addr {
println!("Ok");
parse_with_addr(c, a)
} else {
println!("No");
parse_without_addr(c)
}
*/
}