lipgloss_tree/
children.rs

1//! Node and tree data structures for building hierarchical content.
2//!
3//! This module provides the core data structures for representing tree nodes
4//! and collections of children. It supports styling, filtering, and complex
5//! tree operations with Go lipgloss compatibility.
6
7use lipgloss::Style;
8use std::fmt;
9
10/// Helper trait to enable cloning boxed trait objects for Node.
11///
12/// This trait provides the mechanism for cloning `Box<dyn Node>` objects,
13/// which is necessary for tree operations that need to duplicate node structures.
14/// It's automatically implemented for any type that implements `Node + Clone`.
15///
16/// # Implementation Note
17///
18/// This trait is automatically implemented via a blanket implementation,
19/// so you typically don't need to implement it manually.
20pub trait CloneNode {
21    /// Creates a cloned copy of this node as a boxed trait object.
22    ///
23    /// # Returns
24    ///
25    /// A new `Box<dyn Node>` containing a clone of this node.
26    fn clone_node(&self) -> Box<dyn Node>;
27}
28
29impl<T> CloneNode for T
30where
31    T: 'static + Node + Clone,
32{
33    fn clone_node(&self) -> Box<dyn Node> {
34        Box::new(self.clone())
35    }
36}
37
38/// Trait defining a node in a tree structure.
39///
40/// `Node` represents an individual element in a tree that can have a value,
41/// children, visibility state, and various styling options. It supports both
42/// simple leaf nodes and complex tree nodes with nested children.
43///
44/// # Core Functionality
45///
46/// - **Value**: Each node has a string value that represents its content
47/// - **Children**: Nodes can have child nodes forming a hierarchical structure
48/// - **Visibility**: Nodes can be hidden from rendering
49/// - **Styling**: Nodes support custom enumerators, indenters, and styling functions
50///
51/// # Examples
52///
53/// ```rust
54/// use lipgloss_tree::{Tree, Leaf, Node, Children};
55///
56/// // Create a simple leaf node
57/// let leaf = Leaf::new("Hello", false);
58/// assert_eq!(leaf.value(), "Hello");
59/// assert!(!leaf.hidden());
60///
61/// // Create a tree node with children
62/// let tree = Tree::new()
63///     .root("Parent")
64///     .child(vec!["Child 1".into(), "Child 2".into()]);
65/// assert_eq!(tree.value(), "Parent");
66/// assert_eq!(tree.children().length(), 2);
67/// ```
68pub trait Node: fmt::Display + CloneNode {
69    /// Returns the string value of this node.
70    ///
71    /// The value is the textual content that will be displayed when
72    /// the tree is rendered.
73    ///
74    /// # Returns
75    ///
76    /// The node's value as a `String`
77    fn value(&self) -> String;
78
79    /// Returns the children of this node.
80    ///
81    /// Children are returned as a boxed trait object to allow for
82    /// different implementations of the `Children` trait.
83    ///
84    /// # Returns
85    ///
86    /// A `Box<dyn Children>` containing this node's children
87    fn children(&self) -> Box<dyn Children>;
88
89    /// Returns whether this node is hidden from rendering.
90    ///
91    /// Hidden nodes are not displayed in the tree output and are
92    /// typically filtered out during rendering.
93    ///
94    /// # Returns
95    ///
96    /// `true` if the node is hidden, `false` otherwise
97    fn hidden(&self) -> bool;
98
99    /// Sets the visibility state of this node.
100    ///
101    /// # Arguments
102    ///
103    /// * `hidden` - `true` to hide the node, `false` to show it
104    fn set_hidden(&mut self, hidden: bool);
105
106    /// Updates the value of this node.
107    ///
108    /// # Arguments
109    ///
110    /// * `value` - The new string value for this node
111    fn set_value(&mut self, value: String);
112
113    // Optional per-node renderer overrides. Default to None.
114
115    /// Returns the custom enumerator function for this node, if any.
116    ///
117    /// The enumerator function generates branch characters (like ├──, └──)
118    /// for this specific node, overriding the default renderer behavior.
119    ///
120    /// # Returns
121    ///
122    /// An optional reference to the node's custom enumerator function
123    fn get_enumerator(&self) -> Option<&crate::Enumerator> {
124        None
125    }
126
127    /// Returns the custom indenter function for this node, if any.
128    ///
129    /// The indenter function generates indentation strings for child content
130    /// under this node, overriding the default renderer behavior.
131    ///
132    /// # Returns
133    ///
134    /// An optional reference to the node's custom indenter function
135    fn get_indenter(&self) -> Option<&crate::Indenter> {
136        None
137    }
138
139    /// Returns the base item style for this node, if any.
140    ///
141    /// The base item style is applied to the node's content before any
142    /// style functions are applied.
143    ///
144    /// # Returns
145    ///
146    /// An optional reference to the node's base item style
147    fn get_item_style(&self) -> Option<&Style> {
148        None
149    }
150
151    /// Returns the base enumerator style for this node, if any.
152    ///
153    /// The base enumerator style is applied to the node's branch characters
154    /// before any style functions are applied.
155    ///
156    /// # Returns
157    ///
158    /// An optional reference to the node's base enumerator style
159    fn get_enumerator_style(&self) -> Option<&Style> {
160        None
161    }
162
163    /// Returns the item style function for this node, if any.
164    ///
165    /// The item style function provides dynamic styling based on the node's
166    /// position and context within its parent's children.
167    ///
168    /// # Returns
169    ///
170    /// An optional reference to the node's item style function
171    fn get_item_style_func(&self) -> Option<&crate::StyleFunc> {
172        None
173    }
174
175    /// Returns the enumerator style function for this node, if any.
176    ///
177    /// The enumerator style function provides dynamic styling for branch
178    /// characters based on the node's position and context.
179    ///
180    /// # Returns
181    ///
182    /// An optional reference to the node's enumerator style function
183    fn get_enumerator_style_func(&self) -> Option<&crate::StyleFunc> {
184        None
185    }
186}
187
188impl Clone for NodeChildren {
189    fn clone(&self) -> Self {
190        let mut cloned = NodeChildren::new();
191        for i in 0..self.length() {
192            if let Some(n) = self.at(i) {
193                cloned.append(n.clone_node());
194            }
195        }
196        cloned
197    }
198}
199
200/// A filtered view of children that applies start/end bounds and optional hidden filtering.
201///
202/// `Slice` provides a window into a larger children collection, allowing you to
203/// view only a subset of children within specified bounds. It can also optionally
204/// skip hidden nodes during iteration.
205///
206/// # Examples
207///
208/// ```rust,ignore
209/// // Internal usage only - not part of public API
210/// let slice = Slice::new(children, 1, 5, true); // Skip hidden nodes
211/// ```
212#[allow(dead_code)]
213struct Slice {
214    /// The underlying children collection
215    data: Box<dyn Children>,
216    /// Starting index (inclusive)
217    start: usize,
218    /// Ending index (exclusive)
219    end: usize,
220    /// Whether to skip hidden nodes
221    skip_hidden: bool,
222}
223
224#[allow(dead_code)]
225impl Slice {
226    /// Creates a new slice view of the given children collection.
227    ///
228    /// # Arguments
229    ///
230    /// * `data` - The underlying children collection to slice
231    /// * `start` - Starting index (inclusive)
232    /// * `end` - Ending index (exclusive)
233    /// * `skip_hidden` - Whether to filter out hidden nodes
234    ///
235    /// # Returns
236    ///
237    /// A new `Slice` that provides a filtered view of the children
238    fn new(data: Box<dyn Children>, start: usize, end: usize, skip_hidden: bool) -> Self {
239        Self {
240            data,
241            start,
242            end,
243            skip_hidden,
244        }
245    }
246}
247
248impl Children for Slice {
249    fn at(&self, index: usize) -> Option<&dyn Node> {
250        let mut j = 0usize;
251        let upper = self.end.min(self.data.length());
252        for i in self.start..upper {
253            if let Some(node) = self.data.at(i) {
254                if self.skip_hidden && node.hidden() {
255                    continue;
256                }
257                if j == index {
258                    return Some(node);
259                }
260                j += 1;
261            }
262        }
263        None
264    }
265
266    fn length(&self) -> usize {
267        let mut count = 0usize;
268        let upper = self.end.min(self.data.length());
269        for i in self.start..upper {
270            if let Some(node) = self.data.at(i) {
271                if self.skip_hidden && node.hidden() {
272                    continue;
273                }
274                count += 1;
275            }
276        }
277        count
278    }
279}
280
281/// Trait defining a collection of child nodes in a tree structure.
282///
283/// `Children` provides the interface for accessing and querying collections
284/// of tree nodes. Implementations can provide different storage strategies,
285/// filtering capabilities, or views of the underlying data.
286///
287/// # Examples
288///
289/// ```rust
290/// use lipgloss_tree::{NodeChildren, Children, Leaf, Node};
291///
292/// let mut children = NodeChildren::new();
293/// children.append(Box::new(Leaf::new("Item 1", false)));
294/// children.append(Box::new(Leaf::new("Item 2", false)));
295///
296/// assert_eq!(children.length(), 2);
297/// assert_eq!(children.at(0).unwrap().value(), "Item 1");
298/// ```
299pub trait Children {
300    /// Returns the node at the given index.
301    ///
302    /// # Arguments
303    ///
304    /// * `index` - The zero-based index of the desired node
305    ///
306    /// # Returns
307    ///
308    /// An optional reference to the node at the given index,
309    /// or `None` if the index is out of bounds
310    fn at(&self, index: usize) -> Option<&dyn Node>;
311
312    /// Returns the total number of children in this collection.
313    ///
314    /// # Returns
315    ///
316    /// The count of child nodes as a `usize`
317    fn length(&self) -> usize;
318}
319
320/// A concrete implementation of the `Children` trait using a vector of boxed nodes.
321///
322/// `NodeChildren` is the primary implementation for storing and managing
323/// collections of tree nodes. It provides efficient access, modification,
324/// and iteration over child nodes.
325///
326/// # Examples
327///
328/// ```rust
329/// use lipgloss_tree::{NodeChildren, Leaf, Children};
330///
331/// let mut children = NodeChildren::new();
332/// children.append(Box::new(Leaf::new("First", false)));
333/// children.append(Box::new(Leaf::new("Second", false)));
334///
335/// assert_eq!(children.length(), 2);
336/// ```
337pub struct NodeChildren {
338    /// Vector storing the child nodes as boxed trait objects
339    nodes: Vec<Box<dyn Node>>,
340}
341
342impl NodeChildren {
343    /// Creates a new empty `NodeChildren` collection.
344    ///
345    /// # Examples
346    ///
347    /// ```rust
348    /// use lipgloss_tree::{NodeChildren, Children};
349    ///
350    /// let children = NodeChildren::new();
351    /// assert_eq!(children.length(), 0);
352    /// ```
353    pub fn new() -> Self {
354        Self { nodes: Vec::new() }
355    }
356
357    /// Creates a `NodeChildren` collection from a vector of boxed nodes.
358    ///
359    /// # Arguments
360    ///
361    /// * `nodes` - A vector of boxed nodes to initialize the collection with
362    ///
363    /// # Examples
364    ///
365    /// ```rust
366    /// use lipgloss_tree::{NodeChildren, Leaf, Children};
367    ///
368    /// let nodes = vec![
369    ///     Box::new(Leaf::new("A", false)) as Box<dyn lipgloss_tree::Node>,
370    ///     Box::new(Leaf::new("B", false)) as Box<dyn lipgloss_tree::Node>,
371    /// ];
372    /// let children = NodeChildren::from_nodes(nodes);
373    /// assert_eq!(children.length(), 2);
374    /// ```
375    pub fn from_nodes(nodes: Vec<Box<dyn Node>>) -> Self {
376        Self { nodes }
377    }
378
379    /// Appends a child node to the end of the collection.
380    ///
381    /// # Arguments
382    ///
383    /// * `child` - The boxed node to add to the collection
384    ///
385    /// # Examples
386    ///
387    /// ```rust
388    /// use lipgloss_tree::{NodeChildren, Leaf, Children};
389    ///
390    /// let mut children = NodeChildren::new();
391    /// children.append(Box::new(Leaf::new("New Item", false)));
392    /// assert_eq!(children.length(), 1);
393    /// ```
394    pub fn append(&mut self, child: Box<dyn Node>) {
395        self.nodes.push(child);
396    }
397
398    /// Removes and returns the child node at the given index.
399    ///
400    /// # Arguments
401    ///
402    /// * `index` - The zero-based index of the node to remove
403    ///
404    /// # Returns
405    ///
406    /// The removed node if the index was valid, or `None` if out of bounds
407    ///
408    /// # Examples
409    ///
410    /// ```rust
411    /// use lipgloss_tree::{NodeChildren, Leaf, Children};
412    ///
413    /// let mut children = NodeChildren::new();
414    /// children.append(Box::new(Leaf::new("Remove me", false)));
415    ///
416    /// let removed = children.remove(0);
417    /// assert!(removed.is_some());
418    /// assert_eq!(children.length(), 0);
419    /// ```
420    pub fn remove(&mut self, index: usize) -> Option<Box<dyn Node>> {
421        if index < self.nodes.len() {
422            Some(self.nodes.remove(index))
423        } else {
424            None
425        }
426    }
427
428    /// Returns a mutable reference to the boxed node at the given index.
429    ///
430    /// This allows you to modify the node in place or replace it entirely.
431    ///
432    /// # Arguments
433    ///
434    /// * `index` - The zero-based index of the desired node
435    ///
436    /// # Returns
437    ///
438    /// A mutable reference to the boxed node, or `None` if the index is out of bounds
439    ///
440    /// # Examples
441    ///
442    /// ```rust
443    /// use lipgloss_tree::{NodeChildren, Leaf, Node};
444    ///
445    /// let mut children = NodeChildren::new();
446    /// children.append(Box::new(Leaf::new("Original", false)));
447    ///
448    /// if let Some(node) = children.at_mut(0) {
449    ///     node.set_value("Modified".to_string());
450    /// }
451    /// ```
452    pub fn at_mut(&mut self, index: usize) -> Option<&mut Box<dyn Node>> {
453        self.nodes.get_mut(index)
454    }
455}
456
457impl Default for NodeChildren {
458    /// Creates a default (empty) `NodeChildren` collection.
459    ///
460    /// Equivalent to `NodeChildren::new()` - creates an empty collection
461    /// with no child nodes.
462    fn default() -> Self {
463        Self::new()
464    }
465}
466
467impl Children for NodeChildren {
468    fn at(&self, index: usize) -> Option<&dyn Node> {
469        self.nodes.get(index).map(|node| node.as_ref())
470    }
471
472    fn length(&self) -> usize {
473        self.nodes.len()
474    }
475}
476
477/// A terminal node in the tree that contains a value but no children.
478///
479/// `Leaf` represents the simplest type of tree node - one that holds a string
480/// value and a visibility flag, but cannot have child nodes. This is useful
481/// for representing individual items in a tree structure.
482///
483/// # Examples
484///
485/// ```rust
486/// use lipgloss_tree::{Leaf, Node, Children};
487///
488/// let leaf = Leaf::new("Hello, World!", false);
489/// assert_eq!(leaf.value(), "Hello, World!");
490/// assert!(!leaf.hidden());
491/// assert_eq!(leaf.children().length(), 0);
492///
493/// println!("{}", leaf); // Outputs: Hello, World!
494/// ```
495#[derive(Debug, Clone)]
496pub struct Leaf {
497    /// The textual content of this leaf node
498    value: String,
499    /// Whether this leaf is hidden from rendering
500    hidden: bool,
501}
502
503impl Leaf {
504    /// Creates a new leaf node with the given value and visibility.
505    ///
506    /// # Arguments
507    ///
508    /// * `value` - The content for this leaf (anything convertible to String)
509    /// * `hidden` - Whether this leaf should be hidden from rendering
510    ///
511    /// # Examples
512    ///
513    /// ```rust
514    /// use lipgloss_tree::{Leaf, Node};
515    ///
516    /// let visible_leaf = Leaf::new("Visible", false);
517    /// let hidden_leaf = Leaf::new("Hidden", true);
518    ///
519    /// assert!(!visible_leaf.hidden());
520    /// assert!(hidden_leaf.hidden());
521    /// ```
522    pub fn new(value: impl Into<String>, hidden: bool) -> Self {
523        Self {
524            value: value.into(),
525            hidden,
526        }
527    }
528}
529
530impl Node for Leaf {
531    fn value(&self) -> String {
532        self.value.clone()
533    }
534
535    fn children(&self) -> Box<dyn Children> {
536        Box::new(NodeChildren::new())
537    }
538
539    fn hidden(&self) -> bool {
540        self.hidden
541    }
542
543    fn set_hidden(&mut self, hidden: bool) {
544        self.hidden = hidden;
545    }
546
547    fn set_value(&mut self, value: String) {
548        self.value = value;
549    }
550
551    fn get_enumerator(&self) -> Option<&crate::Enumerator> {
552        None
553    }
554
555    fn get_indenter(&self) -> Option<&crate::Indenter> {
556        None
557    }
558}
559
560impl fmt::Display for Leaf {
561    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
562        write!(f, "{}", self.value)
563    }
564}
565
566/// A tree node that can contain both a value and child nodes.
567///
568/// `Tree` is the main building block for creating hierarchical tree structures.
569/// Unlike `Leaf` nodes, trees can have children and support advanced features
570/// like custom styling, enumerators, indenters, and offset-based child filtering.
571///
572/// # Key Features
573///
574/// - **Hierarchical structure**: Can contain child nodes forming a tree
575/// - **Custom styling**: Support for root, item, and enumerator styling
576/// - **Custom rendering**: Override enumerators and indenters per-node
577/// - **Child filtering**: Use offsets to display only a subset of children
578/// - **Builder pattern**: Fluent API for easy tree construction
579///
580/// # Examples
581///
582/// ```rust
583/// use lipgloss_tree::Tree;
584///
585/// let tree = Tree::new()
586///     .root("My Project")
587///     .child(vec![
588///         "file1.txt".into(),
589///         "file2.txt".into(),
590///         Tree::new()
591///             .root("subfolder")
592///             .child(vec!["nested.txt".into()])
593///             .into(),
594///     ]);
595///
596/// println!("{}", tree);
597/// ```
598///
599/// This creates a tree structure like:
600/// ```text
601/// My Project
602/// ├── file1.txt
603/// ├── file2.txt
604/// ├── subfolder
605/// │   └── nested.txt
606/// ```
607#[derive(Clone)]
608pub struct Tree {
609    /// The root value of this tree node
610    value: String,
611    /// Whether this tree node is hidden from rendering
612    hidden: bool,
613    /// Offset bounds [start, end] for filtering children
614    offset: [usize; 2],
615    /// Collection of child nodes
616    children: NodeChildren,
617
618    // Style and rendering properties
619    /// Custom enumerator function for this tree
620    enumerator: Option<crate::Enumerator>,
621    /// Custom indenter function for this tree
622    indenter: Option<crate::Indenter>,
623    /// Style applied to the root value
624    root_style: Option<Style>,
625    /// Base style applied to all child items
626    item_style: Option<Style>,
627    /// Base style applied to all enumerators
628    enumerator_style: Option<Style>,
629    /// Dynamic styling function for items
630    item_style_func: Option<crate::StyleFunc>,
631    /// Dynamic styling function for enumerators
632    enumerator_style_func: Option<crate::StyleFunc>,
633}
634
635impl Tree {
636    /// Creates a new empty tree with default settings.
637    ///
638    /// The tree starts with no root value, no children, and default
639    /// rendering settings.
640    ///
641    /// # Examples
642    ///
643    /// ```rust
644    /// use lipgloss_tree::{Tree, Node, Children};
645    ///
646    /// let tree = Tree::new();
647    /// assert!(tree.value().is_empty());
648    /// assert_eq!(tree.children().length(), 0);
649    /// ```
650    pub fn new() -> Self {
651        Self {
652            value: String::new(),
653            hidden: false,
654            offset: [0, 0],
655            children: NodeChildren::new(),
656            // CRITICAL FIX: Set default enumerator and indenter so trees don't inherit
657            // from parent List's list_indenter. This prevents spacing conflicts when
658            // trees are nested in lists with 2-space indentation.
659            enumerator: Some(crate::default_enumerator),
660            indenter: Some(crate::default_indenter),
661            root_style: None,
662            item_style: None,
663            enumerator_style: None,
664            item_style_func: None,
665            enumerator_style_func: None,
666        }
667    }
668
669    /// Sets the root value of this tree.
670    ///
671    /// The root value is displayed at the top of the tree when rendered.
672    /// If no root is set, the tree will start directly with its children.
673    ///
674    /// # Arguments
675    ///
676    /// * `root` - The root value (anything convertible to String)
677    ///
678    /// # Examples
679    ///
680    /// ```rust
681    /// use lipgloss_tree::{Tree, Node};
682    ///
683    /// let tree = Tree::new().root("My Root");
684    /// assert_eq!(tree.value(), "My Root");
685    /// ```
686    pub fn root(mut self, root: impl Into<String>) -> Self {
687        self.value = root.into();
688        self
689    }
690
691    /// Sets the visibility of this tree.
692    ///
693    /// Hidden trees are not rendered in the output, but their children
694    /// may still be visible depending on the rendering context.
695    ///
696    /// # Arguments
697    ///
698    /// * `hide` - `true` to hide this tree, `false` to show it
699    ///
700    /// # Examples
701    ///
702    /// ```rust
703    /// use lipgloss_tree::{Tree, Node};
704    ///
705    /// let hidden_tree = Tree::new().root("Hidden").hide(true);
706    /// assert!(hidden_tree.hidden());
707    /// ```
708    pub fn hide(mut self, hide: bool) -> Self {
709        self.hidden = hide;
710        self
711    }
712
713    /// Sets the offset range for displaying children.
714    ///
715    /// This allows you to display only a subset of the tree's children,
716    /// which is useful for pagination or filtering large trees.
717    ///
718    /// # Arguments
719    ///
720    /// * `start` - Starting index (inclusive) for child display
721    /// * `end` - Ending index (exclusive) for child display
722    ///
723    /// # Examples
724    ///
725    /// ```rust
726    /// use lipgloss_tree::Tree;
727    ///
728    /// let tree = Tree::new()
729    ///     .child(vec!["A".into(), "B".into(), "C".into(), "D".into()])
730    ///     .offset(1, 3); // Will only show children B and C
731    /// ```
732    ///
733    /// # Note
734    ///
735    /// If `start > end`, the values will be swapped. If `end` exceeds the
736    /// number of children, it will be clamped to the children count.
737    pub fn offset(mut self, start: usize, end: usize) -> Self {
738        let (start, end) = if start > end {
739            (end, start)
740        } else {
741            (start, end)
742        };
743
744        let end = if end > self.children.length() {
745            self.children.length()
746        } else {
747            end
748        };
749
750        self.offset = [start, end];
751        self
752    }
753
754    /// Adds multiple children to this tree.
755    ///
756    /// This method accepts a vector of boxed nodes and appends them all
757    /// to the tree's children collection. It matches Go's `Child(...any)` method
758    /// for API compatibility.
759    ///
760    /// # Arguments
761    ///
762    /// * `children` - A vector of boxed nodes to add as children
763    ///
764    /// # Examples
765    ///
766    /// ```rust
767    /// use lipgloss_tree::{Tree, Node, Children};
768    ///
769    /// let tree = Tree::new()
770    ///     .root("Parent")
771    ///     .child(vec![
772    ///         "Child 1".into(),
773    ///         "Child 2".into(),
774    ///         Tree::new().root("Nested").into(),
775    ///     ]);
776    ///
777    /// assert_eq!(tree.children().length(), 3);
778    /// ```
779    pub fn child(mut self, children: Vec<Box<dyn Node>>) -> Self {
780        for child in children {
781            self.children.append(child);
782        }
783        self
784    }
785
786    /// Adds a single child to this tree.
787    ///
788    /// This is a convenience method for adding one child at a time,
789    /// accepting anything that can be converted into a boxed node.
790    ///
791    /// # Arguments
792    ///
793    /// * `child` - A node (or convertible value) to add as a child
794    ///
795    /// # Examples
796    ///
797    /// ```rust
798    /// use lipgloss_tree::{Tree, Leaf, Node, Children};
799    ///
800    /// let tree = Tree::new()
801    ///     .root("Parent")
802    ///     .add_child("String child")
803    ///     .add_child(Leaf::new("Leaf child", false))
804    ///     .add_child(Tree::new().root("Tree child"));
805    ///
806    /// assert_eq!(tree.children().length(), 3);
807    /// ```
808    pub fn add_child(mut self, child: impl Into<Box<dyn Node>>) -> Self {
809        self.children.append(child.into());
810        self
811    }
812
813    /// Sets a custom enumerator function for this tree.
814    ///
815    /// The enumerator generates branch characters (like ├──, └──) based on
816    /// each child's position. This overrides the default enumerator for this tree.
817    ///
818    /// # Arguments
819    ///
820    /// * `enumerator` - A function that takes `(children, index)` and returns a string
821    ///
822    /// # Examples
823    ///
824    /// ```rust
825    /// use lipgloss_tree::Tree;
826    ///
827    /// let tree = Tree::new()
828    ///     .root("Custom")
829    ///     .enumerator(|children, i| {
830    ///         if i == children.length() - 1 {
831    ///             "╰──".to_string()  // Rounded last branch
832    ///         } else {
833    ///             "├──".to_string()  // Standard branch
834    ///         }
835    ///     })
836    ///     .child(vec!["A".into(), "B".into()]);
837    /// ```
838    pub fn enumerator(mut self, enumerator: crate::Enumerator) -> Self {
839        self.enumerator = Some(enumerator);
840        self
841    }
842
843    /// Sets a custom indenter function for this tree.
844    ///
845    /// The indenter generates indentation strings for nested child content.
846    /// This overrides the default indenter for this tree.
847    ///
848    /// # Arguments
849    ///
850    /// * `indenter` - A function that takes `(children, index)` and returns an indentation string
851    ///
852    /// # Examples
853    ///
854    /// ```rust
855    /// use lipgloss_tree::Tree;
856    ///
857    /// let tree = Tree::new()
858    ///     .indenter(|children, i| {
859    ///         if i == children.length() - 1 {
860    ///             "    ".to_string()  // Spaces for last child
861    ///         } else {
862    ///             "│   ".to_string()  // Vertical line for continuing
863    ///         }
864    ///     });
865    /// ```
866    pub fn indenter(mut self, indenter: crate::Indenter) -> Self {
867        self.indenter = Some(indenter);
868        self
869    }
870
871    /// Sets the styling for the root value of this tree.
872    ///
873    /// # Arguments
874    ///
875    /// * `style` - The lipgloss `Style` to apply to the root
876    ///
877    /// # Examples
878    ///
879    /// ```rust
880    /// use lipgloss_tree::Tree;
881    /// use lipgloss::Style;
882    ///
883    /// let tree = Tree::new()
884    ///     .root("Styled Root")
885    ///     .root_style(Style::new().bold(true).foreground("blue"));
886    /// ```
887    pub fn root_style(mut self, style: Style) -> Self {
888        self.root_style = Some(style);
889        self
890    }
891
892    /// Sets the base style applied to all child items.
893    ///
894    /// This style is applied to item content before any style functions.
895    ///
896    /// # Arguments
897    ///
898    /// * `style` - The lipgloss `Style` to apply to all items
899    ///
900    /// # Examples
901    ///
902    /// ```rust
903    /// use lipgloss_tree::Tree;
904    /// use lipgloss::Style;
905    ///
906    /// let tree = Tree::new()
907    ///     .child(vec!["Item 1".into(), "Item 2".into()])
908    ///     .item_style(Style::new().foreground("green"));
909    /// ```
910    pub fn item_style(mut self, style: Style) -> Self {
911        self.item_style = Some(style);
912        self
913    }
914
915    /// Sets the base style applied to all enumerators (branch characters).
916    ///
917    /// This style is applied to enumerators before any style functions.
918    ///
919    /// # Arguments
920    ///
921    /// * `style` - The lipgloss `Style` to apply to all enumerators
922    ///
923    /// # Examples
924    ///
925    /// ```rust
926    /// use lipgloss_tree::Tree;
927    /// use lipgloss::Style;
928    ///
929    /// let tree = Tree::new()
930    ///     .child(vec!["Item 1".into(), "Item 2".into()])
931    ///     .enumerator_style(Style::new().foreground("yellow"));
932    /// ```
933    pub fn enumerator_style(mut self, style: Style) -> Self {
934        self.enumerator_style = Some(style);
935        self
936    }
937
938    /// Sets a dynamic styling function for child items.
939    ///
940    /// The function receives the children collection and the current index,
941    /// allowing for context-aware styling decisions.
942    ///
943    /// # Arguments
944    ///
945    /// * `func` - A function that takes `(children, index)` and returns a `Style`
946    ///
947    /// # Examples
948    ///
949    /// ```rust
950    /// use lipgloss_tree::Tree;
951    /// use lipgloss::Style;
952    ///
953    /// let tree = Tree::new()
954    ///     .child(vec!["First".into(), "Second".into(), "Third".into()])
955    ///     .item_style_func(|_children, i| {
956    ///         if i % 2 == 0 {
957    ///             Style::new().foreground("red")
958    ///         } else {
959    ///             Style::new().foreground("blue")
960    ///         }
961    ///     });
962    /// ```
963    pub fn item_style_func(mut self, func: crate::StyleFunc) -> Self {
964        self.item_style_func = Some(func);
965        self
966    }
967
968    /// Sets a dynamic styling function for enumerators (branch characters).
969    ///
970    /// The function receives the children collection and the current index,
971    /// allowing for context-aware styling of branch characters.
972    ///
973    /// # Arguments
974    ///
975    /// * `func` - A function that takes `(children, index)` and returns a `Style`
976    ///
977    /// # Examples
978    ///
979    /// ```rust
980    /// use lipgloss_tree::{Tree, Children};
981    /// use lipgloss::Style;
982    ///
983    /// let tree = Tree::new()
984    ///     .child(vec!["Item 1".into(), "Item 2".into()])
985    ///     .enumerator_style_func(|children, i| {
986    ///         if i == children.length() - 1 {
987    ///             Style::new().foreground("red")   // Last item in red
988    ///         } else {
989    ///             Style::new().foreground("green") // Others in green
990    ///         }
991    ///     });
992    /// ```
993    pub fn enumerator_style_func(mut self, func: crate::StyleFunc) -> Self {
994        self.enumerator_style_func = Some(func);
995        self
996    }
997
998    /// Returns the custom enumerator function for this tree.
999    ///
1000    /// The enumerator function generates branch characters (like ├──, └──) for
1001    /// this tree's children based on their position in the collection. This
1002    /// allows for custom tree rendering styles.
1003    ///
1004    /// # Returns
1005    ///
1006    /// An optional reference to the enumerator function. Returns `Some` if a
1007    /// custom enumerator has been set with [`Tree::enumerator`], or `None`
1008    /// if using the default enumerator.
1009    ///
1010    /// # Examples
1011    ///
1012    /// ```rust
1013    /// use lipgloss_tree::Tree;
1014    ///
1015    /// let tree = Tree::new()
1016    ///     .enumerator(|children, i| {
1017    ///         if i == children.length() - 1 {
1018    ///             "└──".to_string()
1019    ///         } else {
1020    ///             "├──".to_string()
1021    ///         }
1022    ///     });
1023    ///
1024    /// assert!(tree.get_enumerator().is_some());
1025    /// ```
1026    pub fn get_enumerator(&self) -> Option<&crate::Enumerator> {
1027        self.enumerator.as_ref()
1028    }
1029
1030    /// Returns the custom indenter function for this tree.
1031    ///
1032    /// The indenter function generates indentation strings for nested content
1033    /// under this tree's children. This determines how deeply nested items
1034    /// are visually offset in the rendered output.
1035    ///
1036    /// # Returns
1037    ///
1038    /// An optional reference to the indenter function. Returns `Some` if a
1039    /// custom indenter has been set with [`Tree::indenter`], or `None`
1040    /// if using the default indenter.
1041    ///
1042    /// # Examples
1043    ///
1044    /// ```rust
1045    /// use lipgloss_tree::Tree;
1046    ///
1047    /// let tree = Tree::new()
1048    ///     .indenter(|children, i| {
1049    ///         if i == children.length() - 1 {
1050    ///             "    ".to_string()  // Spaces for last child
1051    ///         } else {
1052    ///             "│   ".to_string()  // Vertical line continuing
1053    ///         }
1054    ///     });
1055    ///
1056    /// assert!(tree.get_indenter().is_some());
1057    /// ```
1058    pub fn get_indenter(&self) -> Option<&crate::Indenter> {
1059        self.indenter.as_ref()
1060    }
1061
1062    /// Returns the styling configuration for this tree's root value.
1063    ///
1064    /// The root style is applied to the tree's main value when rendered,
1065    /// allowing for custom colors, formatting, and visual effects on the
1066    /// top-level tree node.
1067    ///
1068    /// # Returns
1069    ///
1070    /// An optional reference to the root style. Returns `Some` if a custom
1071    /// style has been set with [`Tree::root_style`], or `None` if using
1072    /// the default (unstyled) appearance.
1073    ///
1074    /// # Examples
1075    ///
1076    /// ```rust
1077    /// use lipgloss_tree::Tree;
1078    /// use lipgloss::Style;
1079    ///
1080    /// let tree = Tree::new()
1081    ///     .root("Project Root")
1082    ///     .root_style(Style::new().bold(true).foreground("blue"));
1083    ///
1084    /// assert!(tree.get_root_style().is_some());
1085    /// ```
1086    pub fn get_root_style(&self) -> Option<&Style> {
1087        self.root_style.as_ref()
1088    }
1089
1090    /// Returns the dynamic styling function for this tree's child items.
1091    ///
1092    /// The item style function provides context-aware styling based on each
1093    /// child's position within the tree. It receives the children collection
1094    /// and the current child's index, allowing for complex styling logic.
1095    ///
1096    /// # Returns
1097    ///
1098    /// An optional reference to the item style function. Returns `Some` if a
1099    /// custom function has been set with [`Tree::item_style_func`], or `None`
1100    /// if using the default (no dynamic styling).
1101    ///
1102    /// # Examples
1103    ///
1104    /// ```rust
1105    /// use lipgloss_tree::Tree;
1106    /// use lipgloss::Style;
1107    ///
1108    /// let tree = Tree::new()
1109    ///     .child(vec!["Item 1".into(), "Item 2".into()])
1110    ///     .item_style_func(|_children, i| {
1111    ///         if i % 2 == 0 {
1112    ///             Style::new().foreground("red")
1113    ///         } else {
1114    ///             Style::new().foreground("blue")
1115    ///         }
1116    ///     });
1117    ///
1118    /// assert!(tree.get_item_style_func().is_some());
1119    /// ```
1120    pub fn get_item_style_func(&self) -> Option<&crate::StyleFunc> {
1121        self.item_style_func.as_ref()
1122    }
1123
1124    /// Returns the dynamic styling function for this tree's branch characters.
1125    ///
1126    /// The enumerator style function provides context-aware styling for the
1127    /// branch characters (like ├──, └──) based on each child's position. It
1128    /// receives the children collection and current index for styling decisions.
1129    ///
1130    /// # Returns
1131    ///
1132    /// An optional reference to the enumerator style function. Returns `Some`
1133    /// if a custom function has been set with [`Tree::enumerator_style_func`],
1134    /// or `None` if using the default (no dynamic styling).
1135    ///
1136    /// # Examples
1137    ///
1138    /// ```rust
1139    /// use lipgloss_tree::{Tree, Children};
1140    /// use lipgloss::Style;
1141    ///
1142    /// let tree = Tree::new()
1143    ///     .child(vec!["First".into(), "Last".into()])
1144    ///     .enumerator_style_func(|children, i| {
1145    ///         if i == children.length() - 1 {
1146    ///             Style::new().foreground("red")    // Last item
1147    ///         } else {
1148    ///             Style::new().foreground("green")  // Others
1149    ///         }
1150    ///     });
1151    ///
1152    /// assert!(tree.get_enumerator_style_func().is_some());
1153    /// ```
1154    pub fn get_enumerator_style_func(&self) -> Option<&crate::StyleFunc> {
1155        self.enumerator_style_func.as_ref()
1156    }
1157
1158    /// Returns the base styling configuration for this tree's child items.
1159    ///
1160    /// The item style is applied to all child item content before any
1161    /// dynamic style functions are applied. This provides a consistent
1162    /// base appearance for all children in the tree.
1163    ///
1164    /// # Returns
1165    ///
1166    /// An optional reference to the base item style. Returns `Some` if a
1167    /// custom style has been set with [`Tree::item_style`], or `None`
1168    /// if using the default (unstyled) appearance.
1169    ///
1170    /// # Examples
1171    ///
1172    /// ```rust
1173    /// use lipgloss_tree::Tree;
1174    /// use lipgloss::Style;
1175    ///
1176    /// let tree = Tree::new()
1177    ///     .child(vec!["Item 1".into(), "Item 2".into()])
1178    ///     .item_style(Style::new().foreground("green").italic(true));
1179    ///
1180    /// assert!(tree.get_item_style().is_some());
1181    /// ```
1182    pub fn get_item_style(&self) -> Option<&Style> {
1183        self.item_style.as_ref()
1184    }
1185
1186    /// Returns the base styling configuration for this tree's branch characters.
1187    ///
1188    /// The enumerator style is applied to all branch characters (like ├──, └──)
1189    /// before any dynamic style functions are applied. This provides consistent
1190    /// base styling for all tree branch elements.
1191    ///
1192    /// # Returns
1193    ///
1194    /// An optional reference to the base enumerator style. Returns `Some` if a
1195    /// custom style has been set with [`Tree::enumerator_style`], or `None`
1196    /// if using the default (unstyled) appearance.
1197    ///
1198    /// # Examples
1199    ///
1200    /// ```rust
1201    /// use lipgloss_tree::Tree;
1202    /// use lipgloss::Style;
1203    ///
1204    /// let tree = Tree::new()
1205    ///     .child(vec!["Item 1".into(), "Item 2".into()])
1206    ///     .enumerator_style(Style::new().foreground("yellow").bold(true));
1207    ///
1208    /// assert!(tree.get_enumerator_style().is_some());
1209    /// ```
1210    pub fn get_enumerator_style(&self) -> Option<&Style> {
1211        self.enumerator_style.as_ref()
1212    }
1213}
1214
1215impl Default for Tree {
1216    /// Creates a default tree instance.
1217    ///
1218    /// Equivalent to `Tree::new()` - creates an empty tree with no root value,
1219    /// no children, and default rendering settings.
1220    fn default() -> Self {
1221        Self::new()
1222    }
1223}
1224
1225impl Node for Tree {
1226    fn value(&self) -> String {
1227        self.value.clone()
1228    }
1229
1230    fn children(&self) -> Box<dyn Children> {
1231        // Return a subset of children based on offset, cloning nodes to preserve structure
1232        let start = self.offset[0];
1233        let end = if self.offset[1] == 0 {
1234            self.children.length()
1235        } else {
1236            self.children.length().saturating_sub(self.offset[1])
1237        };
1238
1239        let mut filtered_children = NodeChildren::new();
1240        for i in start..end.min(self.children.length()) {
1241            if let Some(node) = self.children.at(i) {
1242                if node.hidden() {
1243                    continue;
1244                }
1245                filtered_children.append(node.clone_node());
1246            }
1247        }
1248        Box::new(filtered_children)
1249    }
1250
1251    fn hidden(&self) -> bool {
1252        self.hidden
1253    }
1254
1255    fn set_hidden(&mut self, hidden: bool) {
1256        self.hidden = hidden;
1257    }
1258
1259    fn set_value(&mut self, value: String) {
1260        self.value = value;
1261    }
1262
1263    fn get_enumerator(&self) -> Option<&crate::Enumerator> {
1264        self.enumerator.as_ref()
1265    }
1266
1267    fn get_indenter(&self) -> Option<&crate::Indenter> {
1268        self.indenter.as_ref()
1269    }
1270
1271    fn get_item_style(&self) -> Option<&Style> {
1272        self.item_style.as_ref()
1273    }
1274
1275    fn get_enumerator_style(&self) -> Option<&Style> {
1276        self.enumerator_style.as_ref()
1277    }
1278
1279    fn get_item_style_func(&self) -> Option<&crate::StyleFunc> {
1280        self.item_style_func.as_ref()
1281    }
1282
1283    fn get_enumerator_style_func(&self) -> Option<&crate::StyleFunc> {
1284        self.enumerator_style_func.as_ref()
1285    }
1286}
1287
1288impl fmt::Display for Tree {
1289    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1290        let mut renderer = crate::renderer::Renderer::new()
1291            .enumerator(self.enumerator.unwrap_or(crate::default_enumerator))
1292            .indenter(self.indenter.unwrap_or(crate::default_indenter));
1293
1294        // Build a TreeStyle snapshot from this Tree and apply to renderer
1295        let style = crate::renderer::TreeStyle {
1296            enumerator_func: self
1297                .enumerator_style_func
1298                .unwrap_or(|_, _| Style::new().padding_right(1)),
1299            item_func: self.item_style_func.unwrap_or(|_, _| Style::new()),
1300            root: self.root_style.clone().unwrap_or_default(),
1301            enumerator_base: self.enumerator_style.clone(),
1302            item_base: self.item_style.clone(),
1303        };
1304        renderer = renderer.style(style);
1305
1306        let output = renderer.render(self, true, "");
1307        write!(f, "{}", output)
1308    }
1309}
1310
1311// Direct conversions to Box<dyn Node> for the simplified API
1312impl From<&str> for Box<dyn Node> {
1313    fn from(s: &str) -> Self {
1314        Box::new(Leaf::new(s.to_string(), false))
1315    }
1316}
1317
1318impl From<String> for Box<dyn Node> {
1319    fn from(s: String) -> Self {
1320        Box::new(Leaf::new(s, false))
1321    }
1322}
1323
1324impl From<Tree> for Box<dyn Node> {
1325    fn from(tree: Tree) -> Self {
1326        Box::new(tree)
1327    }
1328}
1329
1330impl From<Leaf> for Box<dyn Node> {
1331    fn from(leaf: Leaf) -> Self {
1332        Box::new(leaf)
1333    }
1334}
1335
1336/// Creates a new tree with the specified root value.
1337///
1338/// This is a convenience function equivalent to `Tree::new().root(root)`.
1339///
1340/// # Arguments
1341///
1342/// * `root` - The root value for the tree (anything convertible to String)
1343///
1344/// # Returns
1345///
1346/// A new `Tree` instance with the specified root value
1347///
1348/// # Examples
1349///
1350/// ```rust
1351/// use lipgloss_tree::{root, Node, Children};
1352///
1353/// let tree = root("My Project")
1354///     .child(vec!["file1.txt".into(), "file2.txt".into()]);
1355///
1356/// assert_eq!(tree.value(), "My Project");
1357/// assert_eq!(tree.children().length(), 2);
1358/// ```
1359pub fn root(root: impl Into<String>) -> Tree {
1360    Tree::new().root(root)
1361}
1362
1363/// Creates a `NodeChildren` collection from string slice data.
1364///
1365/// This is a convenience function for quickly creating a collection of
1366/// leaf nodes from string data. Each string becomes a visible leaf node.
1367///
1368/// # Arguments
1369///
1370/// * `data` - A slice of string references to convert into leaf nodes
1371///
1372/// # Returns
1373///
1374/// A `NodeChildren` collection containing a leaf node for each string
1375///
1376/// # Examples
1377///
1378/// ```rust
1379/// use lipgloss_tree::{new_string_data, Children, Node};
1380///
1381/// let children = new_string_data(&["Item 1", "Item 2", "Item 3"]);
1382/// assert_eq!(children.length(), 3);
1383/// assert_eq!(children.at(0).unwrap().value(), "Item 1");
1384/// ```
1385pub fn new_string_data(data: &[&str]) -> NodeChildren {
1386    let mut result = NodeChildren::new();
1387    for &item in data {
1388        result.append(Box::new(Leaf::new(item, false)));
1389    }
1390    result
1391}
1392
1393/// A filtered view of children that applies a predicate function.
1394///
1395/// `Filter` wraps a children collection and applies a filtering function
1396/// to determine which children should be visible. Only children that pass
1397/// the filter predicate are accessible through the `Children` interface.
1398///
1399/// # Examples
1400///
1401/// ```rust
1402/// use lipgloss_tree::{Filter, new_string_data, Children};
1403///
1404/// let data = new_string_data(&["A", "B", "C", "D"]);
1405/// let filtered = Filter::new(Box::new(data))
1406///     .filter(|i| i % 2 == 0); // Only even indices
1407///
1408/// assert_eq!(filtered.length(), 2); // Only "A" and "C" are visible
1409/// ```
1410pub struct Filter {
1411    /// The underlying children collection to filter
1412    data: Box<dyn Children>,
1413    /// Optional predicate function for filtering
1414    filter: Option<Box<dyn Fn(usize) -> bool>>,
1415}
1416
1417impl Filter {
1418    /// Creates a new filter with no filtering applied.
1419    ///
1420    /// Initially, all children from the underlying data will be visible.
1421    /// Use the `filter()` method to apply filtering logic.
1422    ///
1423    /// # Arguments
1424    ///
1425    /// * `data` - The children collection to wrap and filter
1426    ///
1427    /// # Examples
1428    ///
1429    /// ```rust
1430    /// use lipgloss_tree::{Filter, new_string_data, Children};
1431    ///
1432    /// let data = new_string_data(&["Item 1", "Item 2"]);
1433    /// let filter = Filter::new(Box::new(data));
1434    /// assert_eq!(filter.length(), 2); // No filtering applied yet
1435    /// ```
1436    pub fn new(data: Box<dyn Children>) -> Self {
1437        Self { data, filter: None }
1438    }
1439
1440    /// Sets the filtering predicate function.
1441    ///
1442    /// The function receives the index of each child in the underlying
1443    /// collection and should return `true` for children that should be
1444    /// visible, `false` for children that should be hidden.
1445    ///
1446    /// # Arguments
1447    ///
1448    /// * `f` - A predicate function that takes an index and returns a boolean
1449    ///
1450    /// # Examples
1451    ///
1452    /// ```rust
1453    /// use lipgloss_tree::{Filter, new_string_data, Children, Node};
1454    ///
1455    /// let data = new_string_data(&["A", "B", "C", "D", "E"]);
1456    /// let filtered = Filter::new(Box::new(data))
1457    ///     .filter(|i| i >= 2); // Only show items at index 2 and higher
1458    ///
1459    /// assert_eq!(filtered.length(), 3); // "C", "D", "E"
1460    /// assert_eq!(filtered.at(0).unwrap().value(), "C");
1461    /// ```
1462    pub fn filter<F>(mut self, f: F) -> Self
1463    where
1464        F: Fn(usize) -> bool + 'static,
1465    {
1466        self.filter = Some(Box::new(f));
1467        self
1468    }
1469}
1470
1471impl Children for Filter {
1472    fn at(&self, index: usize) -> Option<&dyn Node> {
1473        if let Some(ref filter_func) = self.filter {
1474            let mut j = 0;
1475            for i in 0..self.data.length() {
1476                if filter_func(i) {
1477                    if j == index {
1478                        return self.data.at(i);
1479                    }
1480                    j += 1;
1481                }
1482            }
1483            None
1484        } else {
1485            self.data.at(index)
1486        }
1487    }
1488
1489    fn length(&self) -> usize {
1490        if let Some(ref filter_func) = self.filter {
1491            let mut count = 0;
1492            for i in 0..self.data.length() {
1493                if filter_func(i) {
1494                    count += 1;
1495                }
1496            }
1497            count
1498        } else {
1499            self.data.length()
1500        }
1501    }
1502}