parsing to a tree, ugly tree traversal.
This commit is contained in:
parent
35a5c043a0
commit
1df04702a2
|
@ -22,7 +22,7 @@ pub enum FileTreeError {
|
|||
type WeakNodeRef = Weak<RefCell<Node>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct NodeRef(Rc<RefCell<Node>>);
|
||||
pub struct NodeRef(pub Rc<RefCell<Node>>);
|
||||
|
||||
impl Deref for NodeRef {
|
||||
type Target = Rc<RefCell<Node>>;
|
||||
|
@ -44,7 +44,7 @@ impl From<NodeRef> for Rc<RefCell<Node>> {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for NodeRef{
|
||||
impl Display for NodeRef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}", self.borrow())
|
||||
}
|
||||
|
@ -55,6 +55,28 @@ impl NodeRef {
|
|||
node.set_parent(self);
|
||||
self.borrow_mut().add_children(node)
|
||||
}
|
||||
pub fn new_dir(name: String) -> NodeRef {
|
||||
NodeRef(Rc::new(RefCell::new(Node::new_dir(name))))
|
||||
}
|
||||
pub fn add_file(&mut self, name: String, size: usize) -> Result<NodeRef, FileTreeError> {
|
||||
self.add_node(Node::new_file(name, size))
|
||||
}
|
||||
pub fn add_dir(&mut self, name: String) -> Result<NodeRef, FileTreeError> {
|
||||
self.add_node(Node::new_dir(name))
|
||||
}
|
||||
pub fn get_all_dirs(&self) -> Vec<NodeRef> {
|
||||
let mut ret = Vec::new();
|
||||
match &self.borrow().contents {
|
||||
Contents::Size(_) => {}
|
||||
Contents::Children(c) => {
|
||||
ret.push(NodeRef(Rc::clone(self)));
|
||||
for node in c {
|
||||
ret.append(&mut node.get_all_dirs())
|
||||
}
|
||||
}
|
||||
};
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -161,7 +183,7 @@ impl Node {
|
|||
}
|
||||
}
|
||||
|
||||
impl Display for Node{
|
||||
impl Display for Node {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "- {} {}", self.name, self.contents)
|
||||
}
|
||||
|
@ -197,43 +219,87 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_dir_construction() {
|
||||
let mut root = NodeRef(Rc::new(RefCell::new(Node::new_dir("/".to_string()))));
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_node(Node::new_dir("a".to_string())).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("e".to_string())).unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("i".to_string(), 584))
|
||||
.unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("f".to_string(), 29116))
|
||||
.unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("g".to_string(), 2557))
|
||||
.unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("h.lst".to_string(), 62596))
|
||||
.unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("b.txt".to_string(), 14848514))
|
||||
.unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("c.dat".to_string(), 8504156))
|
||||
.unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("j".to_string(), 4060174))
|
||||
.unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("d.log".to_string(), 8033020))
|
||||
.unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("d.ext".to_string(), 5626152))
|
||||
.unwrap();
|
||||
cursor
|
||||
.add_node(Node::new_file("k".to_string(), 7214296))
|
||||
.unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
println!("{}", root);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_size_calcs() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut dirs: Vec<NodeRef> = Vec::new();
|
||||
let mut cursor = root.add_dir("a".to_string()).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
dirs.push(NodeRef(Rc::clone(&cursor)));
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
assert_eq!(Rc::clone(dirs[0].deref()).borrow().get_total_size(), 94853);
|
||||
assert_eq!(Rc::clone(dirs[1].deref()).borrow().get_total_size(), 584);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[2].deref()).borrow().get_total_size(),
|
||||
24933642
|
||||
);
|
||||
}
|
||||
#[test]
|
||||
fn test_get_all_dirs() {
|
||||
let mut root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = root.add_dir("a".to_string()).unwrap();
|
||||
cursor = cursor.add_dir("e".to_string()).unwrap();
|
||||
cursor.add_file("i".to_string(), 584).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||
cursor.add_file("h.lst".to_string(), 62596).unwrap();
|
||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
||||
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||
cursor.add_file("k".to_string(), 7214296).unwrap();
|
||||
let dirs = root.get_all_dirs();
|
||||
let sizes: Vec<usize> = dirs.iter().map(|d| d.borrow().get_total_size()).collect();
|
||||
println!("{:?}", sizes);
|
||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[0].deref()).borrow().get_total_size(),
|
||||
48381165
|
||||
);
|
||||
assert_eq!(Rc::clone(dirs[1].deref()).borrow().get_total_size(), 94853);
|
||||
assert_eq!(Rc::clone(dirs[2].deref()).borrow().get_total_size(), 584);
|
||||
assert_eq!(
|
||||
Rc::clone(dirs[3].deref()).borrow().get_total_size(),
|
||||
24933642
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,7 @@
|
|||
#![allow(unused)]
|
||||
use std::ops::Deref;
|
||||
use std::{cell::RefCell, rc::Rc};
|
||||
|
||||
use crate::file_tree::*;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
@ -77,8 +80,29 @@ pub fn parse(input: &str) -> Node {
|
|||
unimplemented!()
|
||||
}
|
||||
|
||||
pub fn commands_to_tree(input: Vec<Command>) -> Node {
|
||||
unimplemented!()
|
||||
pub fn commands_to_tree(input: Vec<Command>) -> NodeRef {
|
||||
let root = NodeRef::new_dir("/".to_string());
|
||||
let mut cursor = NodeRef(Rc::clone(&root));
|
||||
for command in input {
|
||||
match command {
|
||||
Command::CdRoot => cursor = NodeRef(Rc::clone(&root)),
|
||||
Command::CdUp => cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap(),
|
||||
Command::Cd(name) => cursor = cursor.add_dir(name).unwrap(),
|
||||
Command::Ls(ls) => {
|
||||
for entry in ls {
|
||||
match entry {
|
||||
LsEntry::Dir(d) => {
|
||||
//dirs dont exist until you cd into them.
|
||||
}
|
||||
LsEntry::File(f) => {
|
||||
cursor.add_file(f.name, f.size);
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
root
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -173,4 +197,67 @@ mod tests {
|
|||
]
|
||||
)
|
||||
}
|
||||
#[test]
|
||||
fn test_commands_to_tree() {
|
||||
let 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"),
|
||||
}),
|
||||
]),
|
||||
];
|
||||
let tree = commands_to_tree(input);
|
||||
println!("{}", tree);
|
||||
assert_eq!(Rc::clone(tree.deref()).borrow().get_total_size(), 48381165)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue