From 2fd5dc8c4961a8848a6c255e1e80f4ac91570a7b Mon Sep 17 00:00:00 2001 From: edwloef Date: Fri, 22 Nov 2024 16:08:29 +0100 Subject: [PATCH] docs --- Cargo.toml | 12 +++++++++++- README.md | 20 ++++++++++++++++++++ rustfmt.toml | 1 + src/file.rs | 10 +++++++++- src/folder.rs | 42 +++++++++++++++++++++++++++++++++++++++++- src/lib.rs | 35 +++++++++++++++++++++++++++++++++++ 6 files changed, 117 insertions(+), 3 deletions(-) create mode 100644 README.md create mode 100644 rustfmt.toml diff --git a/Cargo.toml b/Cargo.toml index c153790..dcf3fb7 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,8 +1,13 @@ [package] -name = "iced-file-tree" +name = "iced_file_tree" version = "0.1.0" edition = "2021" license = "MIT" +description = "A lightweight file tree widget for the iced toolkit." +repository = "https://github.com/edwloef/iced-file-tree" +readme = "README.md" +categories = ["gui"] +rust-version = "1.81" [dependencies] iced = { version = "0.13.1", default-features = false, features = [ @@ -19,6 +24,9 @@ rust-2024-compatibility = "warn" unused_crate_dependencies = "warn" unused_qualifications = "warn" +# https://github.com/rust-lang/rust/issues/133167 +if-let-rescope = "allow" + [lints.clippy] pedantic = { level = "warn", priority = -1 } cast_possible_truncation = "allow" @@ -38,6 +46,7 @@ get_unwrap = "warn" lossy_float_literal = "warn" needless_raw_strings = "warn" non_ascii_literal = "warn" +non_zero_suggestions = "warn" print_stdout = "warn" print_stderr = "warn" pub_without_shorthand = "warn" @@ -46,3 +55,4 @@ separated_literal_suffix = "warn" str_to_string = "warn" string_lit_chars_any = "warn" try_err = "warn" +unused_trait_names = "warn" diff --git a/README.md b/README.md new file mode 100644 index 0000000..abb3116 --- /dev/null +++ b/README.md @@ -0,0 +1,20 @@ +# Iced File Tree + +[![Crates.io](https://img.shields.io/crates/v/iced_file_tree.svg)](https://crates.io/crates/iced_file_tree) +[![Documentation](https://docs.rs/iced_file_tree/badge.svg)](https://docs.rs/iced_file_tree) +[![Iced](https://img.shields.io/badge/0.13-blue.svg?logo=iced)](https://github.com/iced-rs/iced/tree/master) +[![License](https://img.shields.io/crates/l/iced_file_tree.svg)](https://github.com/edwloef/iced-file-tree/blob/master/LICENSE) + +A lightweight file tree widget for the [iced](https://github.com/iced-rs/iced/tree/master) toolkit. + +## Usage + +Include `iced_file_tree` as a dependency in your `Cargo.toml`: + +```toml +[dependencies] +iced = "0.13.1" +iced_file_tree = "0.1.0" +``` + +The `FileTree` widget is recommended to be put in an iced [`Scrollable`](https://docs.rs/iced/latest/iced/widget/scrollable/). diff --git a/rustfmt.toml b/rustfmt.toml new file mode 100644 index 0000000..16bdde9 --- /dev/null +++ b/rustfmt.toml @@ -0,0 +1 @@ +format_code_in_doc_comments = true diff --git a/src/file.rs b/src/file.rs index 8ca7578..8138204 100644 --- a/src/file.rs +++ b/src/file.rs @@ -50,10 +50,18 @@ impl<'a, Message> File<'a, Message> { path: PathBuf, on_single_click: Rc Message + 'a>>>>, on_double_click: Rc Message + 'a>>>>, + show_extensions: bool, ) -> Self { debug_assert!(path.is_file()); - let name = path.file_name().unwrap().to_string_lossy().into_owned(); + let name = if show_extensions { + path.file_name() + } else { + path.file_stem() + } + .unwrap() + .to_string_lossy() + .into_owned(); Self { path, diff --git a/src/folder.rs b/src/folder.rs index d177ca3..9e9cafd 100644 --- a/src/folder.rs +++ b/src/folder.rs @@ -30,6 +30,29 @@ struct State { line_height: OnceCell, } +/// A lightweight file tree widget for the [iced](https://github.com/iced-rs/iced/tree/master) toolkit. +/// +/// # Example +/// ```no_run +/// use iced::widget::scrollable; +/// use iced_file_tree::file_tree; +/// +/// enum Message { +/// FileTreeMessage(PathBuf), +/// // ... +/// } +/// +/// fn view(state: &State) -> Element<'_, Message> { +/// let path: PathBuf = /* */ +/// +/// scrollable( +/// file_tree(path) +/// .unwrap() +/// .on_double_click(Message::FileTreeMessage), +/// ) +/// .into() +/// } +/// ``` #[expect(clippy::type_complexity)] pub struct Folder<'a, Message> { path: PathBuf, @@ -38,6 +61,7 @@ pub struct Folder<'a, Message> { on_single_click: Rc Message + 'a>>>>, on_double_click: Rc Message + 'a>>>>, show_hidden: bool, + show_extensions: bool, } impl Debug for Folder<'_, ()> { @@ -53,6 +77,7 @@ impl<'a, Message> Folder<'a, Message> where Message: Clone + 'a, { + /// Creates a new [`FileTree`](crate::FileTree) with the root at the given path. #[must_use] pub fn new(path: PathBuf) -> Option { if std::fs::read_dir(&path).is_err() { @@ -68,9 +93,11 @@ where on_single_click: Rc::default(), on_double_click: Rc::default(), show_hidden: false, + show_extensions: true, }) } + /// Sets the message that will be produced when the user single-clicks on a file within the file tree. #[must_use] pub fn on_single_click(self, on_single_click: impl Fn(PathBuf) -> Message + 'a) -> Self { self.on_single_click @@ -79,6 +106,7 @@ where self } + /// Sets the message that will be produced when the user double-clicks on a file within the file tree. #[must_use] pub fn on_double_click(self, on_double_click: impl Fn(PathBuf) -> Message + 'a) -> Self { self.on_double_click @@ -87,18 +115,27 @@ where self } + /// Enables or disables showing hidden files (disabled by default). #[must_use] - pub fn hidden(mut self, show_hidden: bool) -> Self { + pub fn hidden_files(mut self, show_hidden: bool) -> Self { self.show_hidden = show_hidden; self } + #[must_use] + /// Enables or disables showing file extensions (enabled by default). + pub fn file_extensions(mut self, show_extensions: bool) -> Self { + self.show_extensions = show_extensions; + self + } + #[expect(clippy::type_complexity)] fn new_inner( path: PathBuf, on_single_click: Rc Message + 'a>>>>, on_double_click: Rc Message + 'a>>>>, show_hidden: bool, + show_extensions: bool, ) -> Option { if std::fs::read_dir(&path).is_err() { return None; @@ -113,6 +150,7 @@ where on_single_click, on_double_click, show_hidden, + show_extensions, }) } @@ -150,6 +188,7 @@ where path, self.on_single_click.clone(), self.on_double_click.clone(), + self.show_extensions, ) .into(); file @@ -159,6 +198,7 @@ where self.on_single_click.clone(), self.on_double_click.clone(), self.show_hidden, + self.show_extensions, ) else { return ErrEntry::new_inner(&path).into(); }; diff --git a/src/lib.rs b/src/lib.rs index 0f684a6..e5e3f25 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,41 @@ +//! A lightweight file tree widget for the [iced](https://github.com/iced-rs/iced/tree/master) toolkit. +//! +//! # Example +//! ```no_run +//! use iced::widget::scrollable; +//! use iced_file_tree::file_tree; +//! +//! enum Message { +//! FileTreeMessage(PathBuf), +//! // ... +//! } +//! +//! fn view(state: &State) -> Element<'_, Message> { +//! let path: PathBuf = /* */ +//! +//! scrollable( +//! file_tree(path) +//! .unwrap() +//! .on_double_click(Message::FileTreeMessage), +//! ) +//! .into() +//! } +//! ``` + mod errentry; mod file; mod folder; #[doc(inline)] pub use folder::Folder as FileTree; + +use std::path::PathBuf; + +/// Creates a new [`FileTree`] with the root at the given path. +#[must_use] +pub fn file_tree<'a, Message>(path: PathBuf) -> Option> +where + Message: Clone + 'a, +{ + FileTree::<'a, Message>::new(path) +}