Skip to main content

dioxus_swdir_tree_core/
lib.rs

1//! Framework-free state machine for a lazy-loading directory-tree widget.
2//!
3//! This crate powers the `dioxus-swdir-tree` widget crate but depends on no UI framework
4//! and no async runtime. It models a navigable tree of files and
5//! directories over the [`swdir`] crate's single-level `scan_dir`
6//! primitive, following the design documents of `iced-swdir-tree` v0.7.
7//!
8//! # Architecture
9//!
10//! State transitions are synchronous methods on [`DirectoryTree`]. They
11//! never block on I/O and never spawn tasks; instead, transitions that
12//! require disk access return a [`ScanRequest`] **as data**. The caller —
13//! a Dioxus coroutine, a thread pool, or a test — executes the request
14//! (see [`scan::run`]) off the UI thread and feeds the resulting
15//! [`LoadPayload`] back through [`DirectoryTree::on_loaded`].
16//!
17//! Every scan is tagged with a wrapping `u32` generation. A result is
18//! merged if and only if its generation strictly equals the tree's
19//! current counter; anything else is stale and silently discarded. This
20//! makes the widget safe against out-of-order delivery.
21//!
22//! # Quick start (blocking helper)
23//!
24//! ```no_run
25//! use dioxus_swdir_tree_core::{DirectoryTree, DisplayFilter, SelectionMode};
26//! use dioxus_swdir_tree_core::keyboard::{handle_key, TreeKey, Modifiers};
27//!
28//! let mut tree = DirectoryTree::new("/some/project")
29//!     .with_filter(DisplayFilter::FilesAndFolders);
30//!
31//! // Synchronous convenience path (tests, scripts, examples):
32//! tree.expand_blocking(&tree.config().root_path.clone());
33//!
34//! // Select the root:
35//! tree.on_selected(&tree.config().root_path.clone(), true, SelectionMode::Replace);
36//!
37//! // Navigate down one row with the keyboard:
38//! if let Some(ev) = handle_key(&tree, TreeKey::Down, Modifiers::default()) {
39//!     println!("keyboard event: {ev:?}");
40//! }
41//! ```
42
43pub mod cache;
44pub mod config;
45pub mod drag;
46pub mod entry;
47pub mod error;
48pub mod event;
49pub mod executor;
50pub mod icon;
51pub mod item_event;
52pub mod item_tree;
53pub mod keyboard;
54pub mod node;
55pub mod scan;
56pub mod search;
57pub mod selection;
58pub mod tree;
59
60pub use cache::{CachedScan, TreeCache};
61pub use config::{DEFAULT_PREFETCH_SKIP, DisplayFilter, TreeConfig};
62pub use drag::{DragMsg, DragOutcome, DragState};
63pub use entry::LoadedEntry;
64pub use error::ScanIssue;
65pub use event::DirectoryTreeEvent;
66pub use executor::{ScanExecutor, ScanFuture, ScanJob, ThreadExecutor};
67pub use icon::{IconRole, IconSpec, IconTheme, UnicodeTheme};
68#[cfg(feature = "icons")]
69pub use icon::{LUCIDE_FONT_BYTES, LucideTheme};
70pub use item_event::ItemTreeEvent;
71pub use item_tree::ItemSearchState;
72pub use item_tree::{DropPosition, ItemDragMsg, ItemDragOutcome};
73pub use item_tree::{ItemNode, ItemTree, NodeId, VisibleItem};
74pub use keyboard::{Modifiers, TreeKey, handle_key};
75pub use node::TreeNode;
76pub use scan::{LoadPayload, LoadedOutcome, ScanRequest};
77pub use search::SearchState;
78pub use selection::SelectionMode;
79pub use tree::DirectoryTree;
80
81#[cfg(test)]
82mod tests;