Skip to content

Commit

Permalink
chg: order dir->file and alphabetically
Browse files Browse the repository at this point in the history
  • Loading branch information
ynqa committed Feb 23, 2024
1 parent 200b7c6 commit 802ce0c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 29 deletions.
20 changes: 4 additions & 16 deletions examples/tree.rs
Original file line number Diff line number Diff line change
@@ -1,22 +1,10 @@
use promkit::{error::Result, preset::Tree, tree::Node};

fn main() -> Result {
let mut p = Tree::new(Node::NonLeaf {
id: "root".into(),
children: vec![
Node::NonLeaf {
id: "a".into(),
children: vec![Node::Leaf("aa".into()), Node::Leaf("ab".into())],
children_visible: true,
},
Node::Leaf("b".into()),
Node::Leaf("c".into()),
],
children_visible: true,
})
.title("Select a directory or file")
.tree_lines(10)
.prompt()?;
let mut p = Tree::new(Node::try_from(&std::env::current_dir()?.join("src"))?)
.title("Select a directory or file")
.tree_lines(10)
.prompt()?;
println!("result: {:?}", p.run()?);
Ok(())
}
61 changes: 48 additions & 13 deletions src/core/tree/node.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
use std::{fs, path};

use crate::error::{Error, Result};

/// Represents the kind of a node in a tree structure.
///
/// This enum is used to distinguish between nodes that are currently
Expand Down Expand Up @@ -42,32 +44,65 @@ pub enum Node {
Leaf(String),
}

impl From<&path::PathBuf> for Node {
fn from(dir_path: &path::PathBuf) -> Self {
let mut children = Vec::new();
impl TryFrom<&path::PathBuf> for Node {
type Error = Error;

fn try_from(dir_path: &path::PathBuf) -> Result<Self> {
let mut directories = Vec::new();
let mut files = Vec::new();

if dir_path.is_dir() {
for entry in fs::read_dir(dir_path).expect("Directory cannot be read") {
let entry = entry.expect("Failed to read directory entry");
let path = entry.path();
for entry in fs::read_dir(dir_path)? {
let path = entry?.path();
if path.is_dir() {
children.push(Node::from(&path));
directories.push(Node::try_from(&path)?);
} else if path.is_file() {
children.push(Node::Leaf(
path.file_name().unwrap().to_str().unwrap().to_string(),
files.push(Node::Leaf(
path.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::Other,
"Failed to convert file name to string",
)
})?
.to_string(),
));
}
}
}

Node::NonLeaf {
id: dir_path.file_name().unwrap().to_str().unwrap().to_string(),
directories.sort_by(|a, b| a.id().cmp(b.id()));
files.sort_by(|a, b| a.id().cmp(b.id()));

let mut children = directories;
children.extend(files);

Ok(Node::NonLeaf {
id: dir_path
.file_name()
.and_then(|name| name.to_str())
.ok_or_else(|| {
std::io::Error::new(
std::io::ErrorKind::Other,
"Failed to convert directory name to string",
)
})?
.to_string(),
children,
children_visible: true,
}
children_visible: false,
})
}
}

impl Node {
fn id(&self) -> &String {
match self {
Node::NonLeaf { id, .. } => id,
Node::Leaf(id) => id,
}
}

/// Flattens the tree structure into a vector of `Kind`, including only visible nodes.
///
/// This method performs a depth-first search (DFS) to traverse the tree and collect
Expand Down

0 comments on commit 802ce0c

Please sign in to comment.