use std::collections::BTreeMap;
use std::ops::AddAssign;
use std::path::PathBuf;
use tokei::LanguageType;
pub type NodeId = usize;
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct Stats {
pub code: usize,
pub comments: usize,
pub blanks: usize,
pub files: usize,
}
impl Stats {
pub fn lines(&self) -> usize {
self.code + self.comments + self.blanks
}
}
impl AddAssign for Stats {
fn add_assign(&mut self, rhs: Self) {
self.code += rhs.code;
self.comments += rhs.comments;
self.blanks += rhs.blanks;
self.files += rhs.files;
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NodeKind {
Dir,
File,
}
#[derive(Debug, Clone)]
pub struct TreeNode {
pub name: String,
pub rel_path: PathBuf,
pub kind: NodeKind,
pub depth: usize,
pub parent: Option<NodeId>,
pub children: Vec<NodeId>,
pub expanded: bool,
pub stats: Stats,
pub langs: BTreeMap<LanguageType, Stats>,
pub primary_lang: Option<LanguageType>,
}
impl TreeNode {
pub fn dir(name: String, rel_path: PathBuf, parent: Option<NodeId>, depth: usize) -> Self {
Self {
name,
rel_path,
kind: NodeKind::Dir,
depth,
parent,
children: Vec::new(),
expanded: false,
stats: Stats::default(),
langs: BTreeMap::new(),
primary_lang: None,
}
}
pub fn file(name: String, rel_path: PathBuf, parent: Option<NodeId>, depth: usize) -> Self {
Self {
kind: NodeKind::File,
..Self::dir(name, rel_path, parent, depth)
}
}
pub fn is_dir(&self) -> bool {
self.kind == NodeKind::Dir
}
}
#[derive(Debug, Clone)]
pub struct Tree {
pub nodes: Vec<TreeNode>,
pub root: NodeId,
}
impl Tree {
pub fn totals(&self) -> Stats {
self.nodes[self.root].stats
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SortKey {
Lines,
Code,
Comments,
Blanks,
Files,
Name,
}
impl SortKey {
pub fn next(self) -> Self {
match self {
SortKey::Lines => SortKey::Code,
SortKey::Code => SortKey::Comments,
SortKey::Comments => SortKey::Blanks,
SortKey::Blanks => SortKey::Files,
SortKey::Files => SortKey::Name,
SortKey::Name => SortKey::Lines,
}
}
pub fn label(self) -> &'static str {
match self {
SortKey::Lines => "lines",
SortKey::Code => "code",
SortKey::Comments => "comments",
SortKey::Blanks => "blanks",
SortKey::Files => "files",
SortKey::Name => "name",
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum SortDir {
Asc,
Desc,
}
impl SortDir {
pub fn flip(self) -> Self {
match self {
SortDir::Asc => SortDir::Desc,
SortDir::Desc => SortDir::Asc,
}
}
pub fn arrow(self) -> &'static str {
match self {
SortDir::Asc => "↑",
SortDir::Desc => "↓",
}
}
}