197 lines
4.1 KiB
Rust
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)
|
|
}
|
|
*/
|
|
}
|