summaryrefslogtreecommitdiffstats
path: root/src/node.rs
blob: 522e1bb927fb501ba8d9ef9b39d3b6f5233a7a4b (plain)
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
use crate::platform::get_metadata;
use crate::utils::is_filtered_out_due_to_invert_regex;
use crate::utils::is_filtered_out_due_to_regex;

use regex::Regex;
use serde::Serialize;
use std::cmp::Ordering;
use std::path::PathBuf;

#[derive(Debug, Eq, Clone, Serialize)]
pub struct Node {
    pub name: PathBuf,
    pub size: u64,
    pub children: Vec<Node>,
    pub inode_device: Option<(u64, u64)>,
    pub depth: usize,
}

#[allow(clippy::too_many_arguments)]
pub fn build_node(
    dir: PathBuf,
    children: Vec<Node>,
    filter_regex: &[Regex],
    invert_filter_regex: &[Regex],
    use_apparent_size: bool,
    is_symlink: bool,
    is_file: bool,
    by_filecount: bool,
    depth: usize,
) -> Option<Node> {
    get_metadata(&dir, use_apparent_size).map(|data| {
        let inode_device = if is_symlink && !use_apparent_size {
            None
        } else {
            data.1
        };

        let size = if is_filtered_out_due_to_regex(filter_regex, &dir)
            || is_filtered_out_due_to_invert_regex(invert_filter_regex, &dir)
            || (is_symlink && !use_apparent_size)
            || by_filecount && !is_file
        {
            0
        } else if by_filecount {
            1
        } else {
            data.0
        };

        Node {
            name: dir,
            size,
            children,
            inode_device,
            depth,
        }
    })
}

impl PartialEq for Node {
    fn eq(&self, other: &Self) -> bool {
        self.name == other.name && self.size == other.size && self.children == other.children
    }
}

impl Ord for Node {
    fn cmp(&self, other: &Self) -> Ordering {
        self.size
            .cmp(&other.size)
            .then_with(|| self.name.cmp(&other.name))
            .then_with(|| self.children.cmp(&other.children))
    }
}

impl PartialOrd for Node {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        Some(self.cmp(other))
    }
}