1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
use super::{file_node::FileNode, node::Node};
use std::{cell::RefCell, rc::Rc};
use indexmap::IndexMap;

pub struct DirNode {
    name: String,
    parent_node: Option<Rc<RefCell<DirNode>>>,
    child_dirs: IndexMap<String, Rc<RefCell<DirNode>>>,
    child_files: IndexMap<String, Rc<RefCell<FileNode>>>,
    toc_offset: i64,
}

impl Node for DirNode {
    fn name(&self) -> &String {
        &self.name
    }

    fn parent(&self) -> Option<Rc<RefCell<dyn Node>>> {
        match &self.parent_node {
            Some(parent) => Some(parent.to_owned()),
            None => None,
        }
    }

    fn toc_offset(&self) -> i64 {
        self.toc_offset
    }

    fn path(&self) -> String {
        let mut path = self.name.clone();
        if self.parent_node.is_some() {
            path = format!(
                "{}/{}",
                self.parent_node.clone().unwrap().borrow().path(),
                path
            );
        }
        path
    }
}

impl DirNode {
    pub fn new(
        name: Option<String>,
        parent_node: Option<Rc<RefCell<DirNode>>>,
        toc_offset: Option<i64>,
    ) -> Self {
        Self {
            name: name.unwrap_or(String::new()),
            parent_node,
            child_dirs: IndexMap::new(),
            child_files: IndexMap::new(),
            toc_offset: toc_offset.unwrap_or(0),
        }
    }

    pub fn set_data(
        &mut self,
        name: Option<String>,
        parent_node: Option<Rc<RefCell<DirNode>>>,
        toc_offset: Option<i64>,
    ) {
        if name.is_some() {
            self.name = name.unwrap();
        }
        if parent_node.is_some() {
            self.parent_node = parent_node;
        }
        if toc_offset.is_some() {
            self.toc_offset = toc_offset.unwrap();
        }
    }

    pub fn dir_count(&self) -> usize {
        self.child_dirs.len()
    }

    pub fn file_count(&self) -> usize {
        self.child_files.len()
    }

    pub fn get_child_dir(&self, name: &str) -> Option<Rc<RefCell<DirNode>>> {
        match self.child_dirs.get(name) {
            Some(dir) => Some(dir.to_owned()),
            None => None,
        }
    }

    pub fn get_child_file(&self, name: &str) -> Option<Rc<RefCell<FileNode>>> {
        match self.child_files.get(name) {
            Some(file) => Some(file.to_owned()),
            None => None,
        }
    }

    pub fn child_dirs(&self) -> &IndexMap<String, Rc<RefCell<DirNode>>> {
        &self.child_dirs
    }

    pub fn child_files(&self) -> &IndexMap<String, Rc<RefCell<FileNode>>> {
        &self.child_files
    }

    pub fn add_child_dir(&mut self, dir: Rc<RefCell<DirNode>>) {
        self.child_dirs
            .insert(dir.clone().as_ref().borrow().name().to_string(), dir);
    }

    pub fn add_child_file(&mut self, file: Rc<RefCell<FileNode>>) {
        self.child_files
            .insert(file.clone().as_ref().borrow().name().to_string(), file);
    }
}