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>>;
|
type WeakNodeRef = Weak<RefCell<Node>>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct NodeRef(Rc<RefCell<Node>>);
|
pub struct NodeRef(pub Rc<RefCell<Node>>);
|
||||||
|
|
||||||
impl Deref for NodeRef {
|
impl Deref for NodeRef {
|
||||||
type Target = Rc<RefCell<Node>>;
|
type Target = Rc<RefCell<Node>>;
|
||||||
|
@ -55,6 +55,28 @@ impl NodeRef {
|
||||||
node.set_parent(self);
|
node.set_parent(self);
|
||||||
self.borrow_mut().add_children(node)
|
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)]
|
#[derive(Debug)]
|
||||||
|
@ -197,43 +219,87 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_dir_construction() {
|
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();
|
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 = cursor.add_dir("e".to_string()).unwrap();
|
||||||
cursor
|
cursor.add_file("i".to_string(), 584).unwrap();
|
||||||
.add_node(Node::new_file("i".to_string(), 584))
|
|
||||||
.unwrap();
|
|
||||||
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||||
cursor
|
cursor.add_file("f".to_string(), 29116).unwrap();
|
||||||
.add_node(Node::new_file("f".to_string(), 29116))
|
cursor.add_file("g".to_string(), 2557).unwrap();
|
||||||
.unwrap();
|
cursor.add_file("h.lst".to_string(), 62596).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 = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
cursor = Rc::clone(cursor.deref()).borrow().get_parent().unwrap();
|
||||||
cursor
|
cursor.add_file("b.txt".to_string(), 14848514).unwrap();
|
||||||
.add_node(Node::new_file("b.txt".to_string(), 14848514))
|
cursor.add_file("c.dat".to_string(), 8504156).unwrap();
|
||||||
.unwrap();
|
cursor = cursor.add_dir("d".to_string()).unwrap();
|
||||||
cursor
|
cursor.add_file("j".to_string(), 4060174).unwrap();
|
||||||
.add_node(Node::new_file("c.dat".to_string(), 8504156))
|
cursor.add_file("d.log".to_string(), 8033020).unwrap();
|
||||||
.unwrap();
|
cursor.add_file("d.ext".to_string(), 5626152).unwrap();
|
||||||
cursor = cursor.add_node(Node::new_dir("d".to_string())).unwrap();
|
cursor.add_file("k".to_string(), 7214296).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();
|
|
||||||
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
assert_eq!(Rc::clone(root.deref()).borrow().get_total_size(), 48381165);
|
||||||
println!("{}", root);
|
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)]
|
#![allow(unused)]
|
||||||
|
use std::ops::Deref;
|
||||||
|
use std::{cell::RefCell, rc::Rc};
|
||||||
|
|
||||||
use crate::file_tree::*;
|
use crate::file_tree::*;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
@ -77,8 +80,29 @@ pub fn parse(input: &str) -> Node {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn commands_to_tree(input: Vec<Command>) -> Node {
|
pub fn commands_to_tree(input: Vec<Command>) -> NodeRef {
|
||||||
unimplemented!()
|
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)]
|
#[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