diff --git a/src/directory.rs b/src/directory.rs index b2497e5..1809b17 100644 --- a/src/directory.rs +++ b/src/directory.rs @@ -1,8 +1,9 @@ mod display; mod item; +mod constructors; -use std::fs::{remove_dir_all, remove_file, rename, DirBuilder, File}; -use std::io::Error; +use std::fs::{read_dir, remove_dir_all, remove_file, rename, DirBuilder, File}; +use std::io::{Error, ErrorKind}; use std::path::PathBuf; use tui::widgets::{Block, Borders, List, ListItem}; @@ -23,16 +24,14 @@ pub struct Directory { } impl Directory { pub fn new(root: String) -> Result { - DirBuilder::new() - .recursive(true) - .create(&root)?; - - Ok(Self { - dirs: vec![Item::new(root, 0, false)], - src_name: None, - selection: 0, - editing: false, - }) + match read_dir(&root) { + Ok(d) => constructors::new_from_existing(root, d), + Err(e) => if e.kind() == ErrorKind::NotFound { + constructors::create_new(root) + } else { + Err(e) + } + } } pub fn path(&self) -> PathBuf { diff --git a/src/directory/constructors.rs b/src/directory/constructors.rs new file mode 100644 index 0000000..936b7f4 --- /dev/null +++ b/src/directory/constructors.rs @@ -0,0 +1,53 @@ +use super::{Directory, Item}; + +use std::fs::{read_dir, DirBuilder, ReadDir}; +use std::io::{Error, ErrorKind}; + +pub(super) fn create_new(root: String) -> Result { + DirBuilder::new() + .recursive(true) + .create(&root)?; + + Ok(Directory { + dirs: vec![Item::new(root, 0, false)], + src_name: None, + selection: 0, + editing: false, + }) +} + +pub(super) fn new_from_existing(root: String, d: ReadDir) -> Result { + let mut dirs = vec![Item::new(root, 0, false)]; + + add_items(&mut dirs, 1, d)?; + + Ok(Directory { + dirs, + src_name: None, + selection: 0, + editing: false, + }) +} + +fn add_items(out: &mut Vec, depth: u8, d: ReadDir) -> Result<(), Error> { + for item in d { + let item = item?; + let name = item.file_name() + .into_string() + .map_err(|_| Error::new(ErrorKind::InvalidFilename, "could not display file name"))?; + + match read_dir(item.path()) { + Ok(read) => { + out.push( Item::new(name, depth, false) ); + add_items(out, depth+1, read)?; + }, + Err(e) => if e.kind() == ErrorKind::NotADirectory { + out.push( Item::new(name, depth, true) ); + } else { + return Err(e); + } + } + } + + Ok(()) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index acb9b10..5a08c6e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +#![feature(io_error_more)] + mod args; mod command; mod command_output;