Skip to main content

tui_treelistview/
model.rs

1use std::hash::Hash;
2
3/// Minimal tree contract required by the widget.
4///
5/// A proper tree is expected (not a DAG):
6/// - no cycles (DFS traversal is used directly);
7/// - each node has exactly one parent;
8/// - identifiers are stable between frames (for selection/expansion).
9pub trait TreeModel {
10    /// Node identifier type.
11    type Id: Copy + Eq + Hash;
12
13    /// Returns the root node (or `None` if the tree is empty).
14    fn root(&self) -> Option<Self::Id>;
15    /// Returns the node's children in a deterministic order.
16    fn children(&self, id: Self::Id) -> &[Self::Id];
17    /// Returns `true` if the node exists in the model.
18    fn contains(&self, id: Self::Id) -> bool;
19    /// Returns an approximate size hint (not required to be exact).
20    fn size_hint(&self) -> usize {
21        0
22    }
23}
24
25/// Visibility filter for nodes (used to build a reduced list).
26pub trait TreeFilter<T: TreeModel> {
27    /// Returns `true` if the node matches the filter criteria.
28    fn is_match(&self, model: &T, id: T::Id) -> bool;
29}
30
31impl<T, F> TreeFilter<T> for F
32where
33    T: TreeModel,
34    F: Fn(&T, T::Id) -> bool,
35{
36    #[inline]
37    fn is_match(&self, model: &T, id: T::Id) -> bool {
38        self(model, id)
39    }
40}
41
42/// Configuration for filtered rendering.
43#[derive(Clone, Copy, Debug, PartialEq, Eq)]
44pub enum TreeFilterConfig {
45    /// Filtering is disabled.
46    Disabled,
47    /// Filtering is enabled.
48    Enabled { auto_expand: bool },
49}
50
51impl TreeFilterConfig {
52    /// Creates a configuration with filtering disabled.
53    #[must_use]
54    pub const fn disabled() -> Self {
55        Self::Disabled
56    }
57
58    /// Creates a configuration with filtering enabled and auto-expansion.
59    #[must_use]
60    pub const fn enabled() -> Self {
61        Self::Enabled { auto_expand: true }
62    }
63
64    /// Creates a configuration with filtering enabled and manual expansion.
65    #[must_use]
66    pub const fn enabled_manual_expand() -> Self {
67        Self::Enabled { auto_expand: false }
68    }
69}
70
71impl Default for TreeFilterConfig {
72    fn default() -> Self {
73        Self::disabled()
74    }
75}
76
77/// Filter that matches every node.
78#[derive(Clone, Copy, Debug)]
79pub struct NoFilter;
80
81impl<T: TreeModel> TreeFilter<T> for NoFilter {
82    #[inline]
83    fn is_match(&self, _model: &T, _id: T::Id) -> bool {
84        true
85    }
86}