finished parser, just gotta get that tree working...
This commit is contained in:
parent
c01c4e62d9
commit
3f60887645
3 changed files with 221 additions and 126 deletions
|
@ -3,6 +3,11 @@ use crate::file_tree::*;
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
||||
static IS_COMMAND_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$").unwrap());
|
||||
static PARSE_CD_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^\$ cd (\S*)$").unwrap());
|
||||
static PARSE_LS_ENTRY_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^([[:alnum:]]*) (\S*)$").unwrap());
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub enum Command {
|
||||
CdRoot,
|
||||
|
@ -21,136 +26,151 @@ pub struct ParseFile {
|
|||
size: usize,
|
||||
name: String,
|
||||
}
|
||||
|
||||
//parses a single line
|
||||
pub fn parse_to_commands(input: &str) -> Vec<Command> {
|
||||
let mut ret = Vec::new();
|
||||
let mut lines = input.lines().peekable();
|
||||
while lines.peek().is_some() {
|
||||
let line = lines.next().unwrap();
|
||||
if line == "$ ls" {
|
||||
ret.push(Command::Ls(parse_ls(&mut lines)));
|
||||
} else {
|
||||
let captures = PARSE_CD_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
|
||||
ret.push(match &captures[1] {
|
||||
".." => Command::CdUp,
|
||||
"/" => Command::CdRoot,
|
||||
s => Command::Cd(s.to_string()),
|
||||
})
|
||||
}
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
fn parse_ls(lines: &mut std::iter::Peekable<std::str::Lines<'_>>) -> Vec<LsEntry> {
|
||||
let mut ret: Vec<LsEntry> = Vec::new();
|
||||
while lines.peek().is_some() {
|
||||
// if the next line is a command, then we are at the end of the ls listing.
|
||||
let line = lines.peek().expect("no next line");
|
||||
if IS_COMMAND_REGEX.is_match(line) {
|
||||
break;
|
||||
}
|
||||
let captures = PARSE_LS_ENTRY_REGEX
|
||||
.captures(line)
|
||||
.unwrap_or_else(|| panic!("invalid line {}", line));
|
||||
ret.push(match &captures[1] {
|
||||
"dir" => LsEntry::Dir(captures[2].to_string()),
|
||||
s => LsEntry::File(ParseFile {
|
||||
size: str::parse(&captures[1]).unwrap_or_else(|_| panic!("invalid line {}", line)),
|
||||
name: captures[2].to_string(),
|
||||
}),
|
||||
});
|
||||
lines.next();
|
||||
}
|
||||
ret
|
||||
}
|
||||
|
||||
pub fn parse(input: &str) -> Dir {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn parse_to_tree(input: Vec<Command>) -> Dir {
|
||||
pub fn commands_to_tree(input: Vec<Command>) -> Dir {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
//parses a single line
|
||||
pub fn parse_to_commands(input: &str) -> Vec<Command> {
|
||||
static PARSE_COMMAND_REGEX: Lazy<Regex> = Lazy::new(|| Regex::new(r"^$").unwrap());
|
||||
unimplemented!()
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
// #[cfg(test)]
|
||||
// mod tests {
|
||||
// use super::*;
|
||||
//
|
||||
// /* #[test]
|
||||
// fn test_parse() {
|
||||
// let input = "$ cd /
|
||||
// $ ls
|
||||
// dir a
|
||||
// 14848514 b.txt
|
||||
// 8504156 c.dat
|
||||
// dir d
|
||||
// $ cd a
|
||||
// $ ls
|
||||
// dir e
|
||||
// 29116 f
|
||||
// 2557 g
|
||||
// 62596 h.lst
|
||||
// $ cd e
|
||||
// $ ls
|
||||
// 584 i
|
||||
// $ cd ..
|
||||
// $ cd ..
|
||||
// $ cd d
|
||||
// $ ls
|
||||
// 4060174 j
|
||||
// 8033020 d.log
|
||||
// 5626152 d.ext
|
||||
// 7214296 k";
|
||||
// assert_eq!(parse(input), 0);
|
||||
// } */
|
||||
//
|
||||
// #[test]
|
||||
// fn test_parse_to_commands() {
|
||||
// let input = "$ cd /
|
||||
// $ ls
|
||||
// dir a
|
||||
// 14848514 b.txt
|
||||
// 8504156 c.dat
|
||||
// dir d
|
||||
// $ cd a
|
||||
// $ ls
|
||||
// dir e
|
||||
// 29116 f
|
||||
// 2557 g
|
||||
// 62596 h.lst
|
||||
// $ cd e
|
||||
// $ ls
|
||||
// 584 i
|
||||
// $ cd ..
|
||||
// $ cd ..
|
||||
// $ cd d
|
||||
// $ ls
|
||||
// 4060174 j
|
||||
// 8033020 d.log
|
||||
// 5626152 d.ext
|
||||
// 7214296 k";
|
||||
// assert_eq!(
|
||||
// parse_to_commands(input),
|
||||
// vec![
|
||||
// Command::CdRoot,
|
||||
// Command::Ls(vec![
|
||||
// LsEntry::Dir(String::from("a")),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 14848514,
|
||||
// name: String::from("b.txt")
|
||||
// }),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 8504156,
|
||||
// name: String::from("c.dat")
|
||||
// }),
|
||||
// LsEntry::Dir(String::from("d"))
|
||||
// ]),
|
||||
// Command::Cd(String::from("a")),
|
||||
// Command::Ls(vec![
|
||||
// LsEntry::Dir(String::from("e")),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 29116,
|
||||
// name: String::from("f")
|
||||
// }),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 2557,
|
||||
// name: String::from("g")
|
||||
// }),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 62596,
|
||||
// name: String::from("h.lst")
|
||||
// }),
|
||||
// ]),
|
||||
// Command::Cd(String::from("e")),
|
||||
// Command::Ls(vec![LsEntry::File(ParseFile {
|
||||
// size: 484,
|
||||
// name: String::from("i")
|
||||
// }),]),
|
||||
// Command::CdUp,
|
||||
// Command::CdUp,
|
||||
// Command::Cd(String::from("d")),
|
||||
// Command::Ls(vec![
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 4060174,
|
||||
// name: String::from("j")
|
||||
// }),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 8033020,
|
||||
// name: String::from("d.log")
|
||||
// }),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 5626152,
|
||||
// name: String::from("d.ext")
|
||||
// }),
|
||||
// LsEntry::File(ParseFile {
|
||||
// size: 7214296,
|
||||
// name: String::from("k")
|
||||
// }),
|
||||
// ]),
|
||||
// ]
|
||||
// )
|
||||
// }
|
||||
// }
|
||||
#[test]
|
||||
fn test_parse_to_commands() {
|
||||
let input = concat!(
|
||||
"$ cd /\n",
|
||||
"$ ls\n",
|
||||
"dir a\n",
|
||||
"14848514 b.txt\n",
|
||||
"8504156 c.dat\n",
|
||||
"dir d\n",
|
||||
"$ cd a\n",
|
||||
"$ ls\n",
|
||||
"dir e\n",
|
||||
"29116 f\n",
|
||||
"2557 g\n",
|
||||
"62596 h.lst\n",
|
||||
"$ cd e\n",
|
||||
"$ ls\n",
|
||||
"584 i\n",
|
||||
"$ cd ..\n",
|
||||
"$ cd ..\n",
|
||||
"$ cd d\n",
|
||||
"$ ls\n",
|
||||
"4060174 j\n",
|
||||
"8033020 d.log\n",
|
||||
"5626152 d.ext\n",
|
||||
"7214296 k"
|
||||
);
|
||||
assert_eq!(
|
||||
parse_to_commands(input),
|
||||
vec![
|
||||
Command::CdRoot,
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("a")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 14848514,
|
||||
name: String::from("b.txt")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8504156,
|
||||
name: String::from("c.dat")
|
||||
}),
|
||||
LsEntry::Dir(String::from("d"))
|
||||
]),
|
||||
Command::Cd(String::from("a")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::Dir(String::from("e")),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 29116,
|
||||
name: String::from("f")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 2557,
|
||||
name: String::from("g")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 62596,
|
||||
name: String::from("h.lst")
|
||||
}),
|
||||
]),
|
||||
Command::Cd(String::from("e")),
|
||||
Command::Ls(vec![LsEntry::File(ParseFile {
|
||||
size: 584,
|
||||
name: String::from("i")
|
||||
}),]),
|
||||
Command::CdUp,
|
||||
Command::CdUp,
|
||||
Command::Cd(String::from("d")),
|
||||
Command::Ls(vec![
|
||||
LsEntry::File(ParseFile {
|
||||
size: 4060174,
|
||||
name: String::from("j")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 8033020,
|
||||
name: String::from("d.log")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 5626152,
|
||||
name: String::from("d.ext")
|
||||
}),
|
||||
LsEntry::File(ParseFile {
|
||||
size: 7214296,
|
||||
name: String::from("k")
|
||||
}),
|
||||
]),
|
||||
]
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue