mind_tree/
node.rs

1//! Node operations
2
3use crate::encoding::{self, TreeType};
4use serde::{Deserialize, Serialize};
5use std::{
6  cell::RefCell,
7  io::{self, Write},
8  path::PathBuf,
9  rc::{Rc, Weak},
10};
11use thiserror::Error;
12
13#[derive(Clone, Debug, Deserialize, Serialize)]
14#[serde(from = "encoding::Tree", into = "encoding::Tree")]
15pub struct Tree {
16  version: encoding::Version,
17  ty: TreeType,
18  node: Node,
19}
20
21impl From<encoding::Tree> for Tree {
22  fn from(value: encoding::Tree) -> Self {
23    Self::from_encoding(value)
24  }
25}
26
27impl From<Tree> for encoding::Tree {
28  fn from(value: Tree) -> Self {
29    value.into_encoding()
30  }
31}
32
33impl Tree {
34  pub fn new(name: impl AsRef<str>, icon: impl AsRef<str>) -> Self {
35    Self {
36      version: encoding::Version::current(),
37      ty: TreeType::Root,
38      node: Node::new(name, icon),
39    }
40  }
41
42  pub fn from_encoding(tree: encoding::Tree) -> Self {
43    Self {
44      version: tree.version,
45      ty: tree.ty,
46      node: Node::from_encoding(tree.node),
47    }
48  }
49
50  pub fn into_encoding(&self) -> encoding::Tree {
51    encoding::Tree {
52      version: self.version,
53      ty: self.ty,
54      node: self.node.into_encoding(),
55    }
56  }
57
58  /// Get the root node.
59  pub fn root(&self) -> Node {
60    self.node.clone()
61  }
62
63  /// Get a [`Node`] by line number.
64  ///
65  /// 0-indexed.
66  pub fn get_node_by_line(&self, line: usize) -> Option<Node> {
67    let (_, node) = self.node.get_node_by_line(line);
68    node
69  }
70
71  /// Get a [`Node`] by path, e.g. `/root/a/b/c/d`.
72  pub fn get_node_by_path<'a>(
73    &self,
74    path: impl IntoIterator<Item = &'a str>,
75    auto_create_nodes: bool,
76  ) -> Option<Node> {
77    self
78      .node
79      .get_node_by_path(path.into_iter(), auto_create_nodes)
80  }
81}
82
83/// Weak version of [`Node`], mainly for parent nodes.
84///
85/// Not supposed to be used as-is; convert to [`Node`] when needed.
86#[derive(Clone, Debug)]
87pub struct WeakNode {
88  inner: Weak<RefCell<NodeInner>>,
89}
90
91impl WeakNode {
92  fn upgrade(&self) -> Option<Node> {
93    self.inner.upgrade().map(|inner| Node { inner })
94  }
95}
96
97#[derive(Clone, Debug, Deserialize, Serialize)]
98#[serde(from = "encoding::Node", into = "encoding::Node")]
99pub struct Node {
100  inner: Rc<RefCell<NodeInner>>,
101}
102
103impl PartialEq for Node {
104  fn eq(&self, other: &Self) -> bool {
105    self.inner.as_ptr().eq(&other.inner.as_ptr())
106  }
107}
108
109impl From<encoding::Node> for Node {
110  fn from(value: encoding::Node) -> Self {
111    Self::from_encoding(value)
112  }
113}
114
115impl From<Node> for encoding::Node {
116  fn from(value: Node) -> Self {
117    value.into_encoding()
118  }
119}
120
121impl Node {
122  pub fn new(name: impl AsRef<str>, icon: impl AsRef<str>) -> Self {
123    Self::new_raw(name.as_ref(), icon.as_ref(), false, None)
124  }
125
126  fn new_raw(name: &str, icon: &str, is_expanded: bool, parent: Option<WeakNode>) -> Self {
127    let name = name.trim().to_owned();
128
129    // we only trim left because sometimes, the right space is meaningful for some icons
130    let icon = icon.trim_start().to_owned();
131
132    Self {
133      inner: Rc::new(RefCell::new(NodeInner {
134        name,
135        icon,
136        is_expanded,
137        parent,
138        data: None,
139        children: Vec::new(),
140      })),
141    }
142  }
143
144  fn downgrade(&self) -> WeakNode {
145    WeakNode {
146      inner: Rc::downgrade(&self.inner),
147    }
148  }
149
150  pub fn from_encoding(node: encoding::Node) -> Self {
151    Self::from_encoding_rec(None, node)
152  }
153
154  fn from_encoding_rec(parent: Option<WeakNode>, mut node: encoding::Node) -> Self {
155    let current = Self::new_raw(
156      &node
157        .contents
158        .pop()
159        .map(|text| text.text)
160        .unwrap_or_default(),
161      &node.icon,
162      node.is_expanded,
163      parent,
164    );
165
166    let children = node
167      .children
168      .into_iter()
169      .map(|node| Self::from_encoding_rec(Some(current.downgrade()), node))
170      .collect();
171
172    let data = node
173      .data
174      .map(NodeData::file)
175      .or_else(move || node.url.map(NodeData::link));
176
177    {
178      let mut inner = current.inner.borrow_mut();
179      inner.children = children;
180      inner.data = data;
181    }
182
183    current
184  }
185
186  pub fn into_encoding(&self) -> encoding::Node {
187    let node = self.inner.borrow();
188    let data;
189    let url;
190
191    match node.data {
192      Some(NodeData::File(ref path)) => {
193        data = Some(path.clone());
194        url = None;
195      }
196
197      Some(NodeData::Link(ref link)) => {
198        url = Some(link.clone());
199        data = None;
200      }
201
202      None => {
203        data = None;
204        url = None;
205      }
206    }
207
208    encoding::Node {
209      icon: node.icon.clone(),
210      is_expanded: node.is_expanded,
211      contents: vec![encoding::Text {
212        text: node.name.clone(),
213      }],
214      data,
215      url,
216      children: node.children.iter().map(Self::into_encoding).collect(),
217    }
218  }
219
220  fn get_node_by_line(&self, mut line: usize) -> (usize, Option<Self>) {
221    let node = self.inner.borrow();
222
223    if line == 0 {
224      return (0, Some(self.clone()));
225    }
226
227    // jump the current node
228    line -= 1;
229
230    if !node.is_expanded || node.children.is_empty() {
231      return (line, None);
232    }
233
234    for child in &node.children {
235      let (new_line, node) = child.get_node_by_line(line);
236      if node.is_some() {
237        return (new_line, node);
238      }
239
240      line = new_line;
241    }
242
243    (line, None)
244  }
245
246  fn get_node_by_path<'a>(
247    &self,
248    mut path: impl Iterator<Item = &'a str>,
249    auto_create_nodes: bool,
250  ) -> Option<Self> {
251    let node = self.inner.borrow();
252
253    match path.next() {
254      None => Some(self.clone()),
255
256      Some(node_name) => {
257        // find the node in the children list, and if it doesn’t exist, it means the node we are looking for doesn’t exist;
258        // abort early if we don’t need to create the node
259        match node
260          .children
261          .iter()
262          .find(|node| node.inner.borrow().name == node_name)
263        {
264          Some(child) => child.get_node_by_path(path, auto_create_nodes),
265          None => {
266            drop(node);
267
268            if auto_create_nodes {
269              let child = Node::new(node_name, "");
270              self.insert_bottom(child.clone());
271              child.get_node_by_path(path, auto_create_nodes)
272            } else {
273              None
274            }
275          }
276        }
277      }
278    }
279  }
280
281  /// Get the index of a [`Node`] in the node passed as argument, which must be its parent.
282  ///
283  /// If we don’t have any parent, returns `None`.
284  fn get_index(&self, parent: &Node) -> Result<usize, NodeError> {
285    for (i, child) in parent.inner.borrow().children.iter().enumerate() {
286      if self == child {
287        return Ok(i);
288      }
289    }
290
291    Err(NodeError::NotContainedInParent)
292  }
293
294  #[cfg(test)]
295  fn get_index_from_parent(&self) -> Result<usize, NodeError> {
296    self.parent().and_then(|parent| self.get_index(&parent))
297  }
298
299  pub fn name(&self) -> String {
300    self.inner.borrow().name.to_owned()
301  }
302
303  pub fn set_name(&self, name: impl AsRef<str>) -> Result<(), NodeError> {
304    let name = name.as_ref().trim().to_owned();
305
306    if name.is_empty() {
307      return Err(NodeError::EmptyName);
308    }
309
310    self.inner.borrow_mut().name = name;
311    Ok(())
312  }
313
314  pub fn icon(&self) -> String {
315    self.inner.borrow().icon.to_owned()
316  }
317
318  pub fn set_icon(&self, icon: impl AsRef<str>) {
319    let icon = icon.as_ref().trim().to_owned();
320    self.inner.borrow_mut().icon = icon;
321  }
322
323  pub fn data(&self) -> Option<NodeData> {
324    self.inner.borrow().data.clone()
325  }
326
327  pub fn set_data(&self, data: NodeData) -> Result<(), NodeError> {
328    let current = self.inner.borrow();
329
330    match (current.data.as_ref(), &data) {
331      // if nothing is set, set it
332      (None, NodeData::Link(link)) => {
333        if link.is_empty() {
334          return Err(NodeError::NoData);
335        }
336
337        drop(current);
338        self.inner.borrow_mut().data = Some(data);
339      }
340
341      (None, NodeData::File(path)) => {
342        if path.as_os_str().is_empty() {
343          return Err(NodeError::NoData);
344        }
345
346        drop(current);
347        self.inner.borrow_mut().data = Some(data);
348      }
349
350      (Some(NodeData::Link(_)), NodeData::Link(_)) => {
351        drop(current);
352        self.inner.borrow_mut().data = Some(data)
353      }
354
355      (Some(NodeData::File(_)), NodeData::File(_)) => return Err(NodeError::FileDataAlreadyExists),
356
357      // otherwise it’s a data type mismatch
358      _ => return Err(NodeError::MismatchDataType),
359    }
360
361    Ok(())
362  }
363
364  pub fn is_expanded(&self) -> bool {
365    self.inner.borrow().is_expanded
366  }
367
368  pub fn set_expanded(&self, is_expanded: bool) {
369    self.inner.borrow_mut().is_expanded = is_expanded;
370  }
371
372  pub fn parent(&self) -> Result<Node, NodeError> {
373    self
374      .inner
375      .borrow()
376      .parent
377      .as_ref()
378      .and_then(WeakNode::upgrade)
379      .ok_or(NodeError::NoParent)
380  }
381
382  pub fn insert_top(&self, node: Node) {
383    node.inner.borrow_mut().parent = Some(self.downgrade());
384    self.inner.borrow_mut().children.insert(0, node);
385  }
386
387  pub fn insert_bottom(&self, node: Node) {
388    node.inner.borrow_mut().parent = Some(self.downgrade());
389    self.inner.borrow_mut().children.push(node);
390  }
391
392  pub fn insert_before(&self, node: Node) -> Result<(), NodeError> {
393    let parent = self.parent()?;
394    let i = self.get_index(&parent)?;
395
396    node.inner.borrow_mut().parent = Some(parent.downgrade());
397    parent.inner.borrow_mut().children.insert(i, node);
398    Ok(())
399  }
400
401  pub fn insert_after(&self, node: Node) -> Result<(), NodeError> {
402    let parent = self.parent()?;
403    let i = self.get_index(&parent)? + 1;
404
405    node.inner.borrow_mut().parent = Some(parent.downgrade());
406    parent.inner.borrow_mut().children.insert(i, node);
407    Ok(())
408  }
409
410  pub fn delete(&self, node: Node) -> Result<(), NodeError> {
411    let mut inner = self.inner.borrow_mut();
412    let i = inner
413      .children
414      .iter()
415      .enumerate()
416      .find_map(|(i, n)| if n == &node { Some(i) } else { None })
417      .ok_or(NodeError::NotContainedInParent)?;
418
419    let _ = inner.children.remove(i);
420    Ok(())
421  }
422
423  pub fn move_top(&self, node: Node) -> Result<(), NodeError> {
424    let parent = node.parent()?;
425
426    parent.delete(node.clone())?;
427    self.insert_top(node);
428    Ok(())
429  }
430
431  pub fn move_bottom(&self, node: Node) -> Result<(), NodeError> {
432    let parent = node.parent()?;
433
434    parent.delete(node.clone())?;
435    self.insert_bottom(node);
436    Ok(())
437  }
438
439  pub fn move_before(&self, node: Node) -> Result<(), NodeError> {
440    let parent = node.parent()?;
441
442    parent.delete(node.clone())?;
443    self.insert_before(node)?;
444    Ok(())
445  }
446
447  pub fn move_after(&self, node: Node) -> Result<(), NodeError> {
448    let parent = node.parent()?;
449
450    parent.delete(node.clone())?;
451    self.insert_after(node)?;
452    Ok(())
453  }
454
455  pub fn toggle_expand(&self) {
456    let mut node = self.inner.borrow_mut();
457    node.is_expanded = !node.is_expanded;
458  }
459
460  pub fn paths(&self, prefix: impl AsRef<str>, filter: NodeFilter) -> Vec<String> {
461    let prefix = prefix.as_ref();
462    let mut all_paths = Vec::new();
463
464    if filter.accepts(self) {
465      all_paths.push(prefix.to_owned());
466    }
467
468    let prefix = if prefix == "/" { "" } else { prefix };
469    self.paths_rec(prefix, &mut all_paths, filter);
470    all_paths
471  }
472
473  fn paths_rec(&self, parent: &str, paths: &mut Vec<String>, filter: NodeFilter) {
474    for child in &self.inner.borrow().children {
475      let path = format!("{parent}/{name}", name = child.name());
476
477      if filter.accepts(child) {
478        paths.push(path.clone());
479      }
480
481      child.paths_rec(&path, paths, filter);
482    }
483  }
484
485  /// Write paths to the provided writer.
486  pub fn write_paths(
487    &self,
488    prefix: &str,
489    filter: NodeFilter,
490    writer: &mut impl Write,
491  ) -> Result<(), NodeError> {
492    for path in self.paths(prefix, filter) {
493      writeln!(writer, "{}", path).map_err(NodeError::CannotWritePaths)?;
494    }
495
496    Ok(())
497  }
498}
499
500#[derive(Clone, Debug)]
501pub struct NodeInner {
502  name: String,
503  icon: String,
504  is_expanded: bool,
505  parent: Option<WeakNode>,
506  data: Option<NodeData>,
507  children: Vec<Node>,
508}
509
510#[derive(Clone, Debug, Eq, PartialEq)]
511pub enum NodeData {
512  File(PathBuf),
513  Link(String),
514}
515
516impl NodeData {
517  pub fn file(path: impl Into<PathBuf>) -> Self {
518    NodeData::File(path.into())
519  }
520
521  pub fn link(link: impl Into<String>) -> Self {
522    NodeData::Link(link.into())
523  }
524}
525
526#[derive(Clone, Copy, Debug, Default, Eq, PartialEq)]
527pub enum NodeFilter {
528  #[default]
529  Always,
530  FileOrLink,
531  FileOnly,
532  LinkOnly,
533}
534
535impl NodeFilter {
536  pub fn new(file: bool, uri: bool) -> Self {
537    match (file, uri) {
538      (true, true) => Self::FileOrLink,
539      (true, false) => Self::FileOnly,
540      (false, true) => Self::LinkOnly,
541      (false, false) => Self::Always,
542    }
543  }
544
545  fn accepts(&self, node: &Node) -> bool {
546    match self {
547      NodeFilter::Always => true,
548      NodeFilter::FileOrLink => node.inner.borrow().data.is_some(),
549      NodeFilter::FileOnly => matches!(node.inner.borrow().data, Some(NodeData::File(..))),
550      NodeFilter::LinkOnly => matches!(node.inner.borrow().data, Some(NodeData::Link(..))),
551    }
552  }
553}
554
555#[derive(Debug, Error)]
556pub enum NodeError {
557  #[error("cannot insert; no parent")]
558  NoParent,
559
560  #[error("the node is not contained in its supposed parent")]
561  NotContainedInParent,
562
563  #[error("cannot set name; name cannot be empty")]
564  EmptyName,
565
566  #[error("cannot set data; file data already exists")]
567  FileDataAlreadyExists,
568
569  #[error("cannot set data; already exists with a different type")]
570  MismatchDataType,
571
572  #[error("no data")]
573  NoData,
574
575  #[error("cannot create associated data file: {0}")]
576  CannotCreateDataFile(io::Error),
577
578  #[error("cannot write paths")]
579  CannotWritePaths(io::Error),
580}
581
582/// Split a string in the form of `/NodeA/NodeB/…` into an iterator of path segment.
583///
584/// Use that function to pass to various tree and node API functions expecting a path.
585pub fn path_iter(path: &str) -> impl Iterator<Item = &str> {
586  path.split('/').filter(|frag| !frag.trim().is_empty())
587}
588
589#[cfg(test)]
590mod tests {
591  use crate::{
592    encoding::{self, TreeType, Version},
593    node::{Node, NodeData, NodeError, NodeFilter, Tree},
594  };
595
596  use super::path_iter;
597
598  #[test]
599  fn path_iter_test() {
600    assert_eq!(path_iter("").collect::<Vec<_>>(), Vec::<&str>::new());
601    assert_eq!(path_iter("/").collect::<Vec<_>>(), Vec::<&str>::new());
602    assert_eq!(path_iter("//").collect::<Vec<_>>(), Vec::<&str>::new());
603    assert_eq!(
604      path_iter("/Foo/Bar/Zoo").collect::<Vec<_>>(),
605      vec!["Foo", "Bar", "Zoo"]
606    );
607
608    assert_eq!(path_iter("/A B").collect::<Vec<_>>(), vec!["A B"]);
609  }
610
611  #[test]
612  fn get_node_by_line_no_child() {
613    let tree = Tree::from_encoding(encoding::Tree {
614      version: Version::default(),
615      ty: TreeType::Root,
616      node: encoding::Node::new_by_expand_state("root", false, vec![]),
617    });
618
619    assert_eq!(
620      tree
621        .get_node_by_line(0)
622        .as_ref()
623        .map(|node| node.inner.borrow())
624        .as_ref()
625        .map(|node| node.name.as_str()),
626      Some("root")
627    );
628    assert_eq!(tree.get_node_by_line(1), None);
629    assert_eq!(tree.get_node_by_line(2), None);
630
631    let tree = Tree::from_encoding(encoding::Tree {
632      version: Version::default(),
633      ty: TreeType::Root,
634      node: encoding::Node::new_by_expand_state("root", true, vec![]),
635    });
636
637    assert_eq!(
638      tree
639        .get_node_by_line(0)
640        .as_ref()
641        .map(|node| node.inner.borrow())
642        .as_ref()
643        .map(|node| node.name.as_str()),
644      Some("root")
645    );
646    assert_eq!(
647      tree
648        .get_node_by_line(0)
649        .as_ref()
650        .map(|node| node.inner.borrow())
651        .as_ref()
652        .map(|node| node.name.as_str()),
653      Some("root")
654    );
655    assert_eq!(tree.get_node_by_line(1), None);
656    assert_eq!(tree.get_node_by_line(2), None);
657  }
658
659  // this tests a couple of queries on this tree:
660  //
661  // root/       expanded     line:0
662  //   a/        collapsed    line:1
663  //     x/
664  //     y/
665  //   b/        expanded     line:2
666  //     z/
667  //   c/
668  #[test]
669  fn get_node_by_line_with_children() {
670    let tree = Tree::from_encoding(encoding::Tree {
671      version: Version::default(),
672      ty: TreeType::Root,
673      node: encoding::Node::new_by_expand_state(
674        "root",
675        true,
676        vec![
677          encoding::Node::new_by_expand_state(
678            "a",
679            false,
680            vec![
681              encoding::Node::new_by_expand_state("x", false, vec![]),
682              encoding::Node::new_by_expand_state("y", false, vec![]),
683            ],
684          ),
685          encoding::Node::new_by_expand_state(
686            "b",
687            true,
688            vec![encoding::Node::new_by_expand_state("z", false, vec![])],
689          ),
690          encoding::Node::new_by_expand_state("c", false, vec![]),
691        ],
692      ),
693    });
694
695    assert_eq!(
696      tree
697        .get_node_by_line(0)
698        .as_ref()
699        .map(|node| node.inner.borrow())
700        .as_ref()
701        .map(|node| node.name.as_str()),
702      Some("root")
703    );
704    assert_eq!(
705      tree
706        .get_node_by_line(1)
707        .as_ref()
708        .map(|node| node.inner.borrow())
709        .as_ref()
710        .map(|node| node.name.as_str()),
711      Some("a")
712    );
713    assert_eq!(
714      tree
715        .get_node_by_line(2)
716        .as_ref()
717        .map(|node| node.inner.borrow())
718        .as_ref()
719        .map(|node| node.name.as_str()),
720      Some("b")
721    );
722    assert_eq!(
723      tree
724        .get_node_by_line(3)
725        .as_ref()
726        .map(|node| node.inner.borrow())
727        .as_ref()
728        .map(|node| node.name.as_str()),
729      Some("z")
730    );
731    assert_eq!(
732      tree
733        .get_node_by_line(4)
734        .as_ref()
735        .map(|node| node.inner.borrow())
736        .as_ref()
737        .map(|node| node.name.as_str()),
738      Some("c")
739    );
740  }
741
742  #[test]
743  fn get_node_by_path_no_child() {
744    let tree = Tree::from_encoding(encoding::Tree {
745      version: Version::default(),
746      ty: TreeType::Root,
747      node: encoding::Node::new_by_expand_state("root", false, vec![]),
748    });
749
750    assert_eq!(
751      tree
752        .get_node_by_line(0)
753        .as_ref()
754        .map(|node| node.inner.borrow())
755        .as_ref()
756        .map(|node| node.name.as_str()),
757      Some("root")
758    );
759    assert_eq!(tree.get_node_by_path(["test"], false), None);
760
761    let tree = Tree::from_encoding(encoding::Tree {
762      version: Version::default(),
763      ty: TreeType::Root,
764      node: encoding::Node::new_by_expand_state("root", true, vec![]),
765    });
766
767    assert_eq!(
768      tree
769        .get_node_by_line(0)
770        .as_ref()
771        .map(|node| node.inner.borrow())
772        .as_ref()
773        .map(|node| node.name.as_str()),
774      Some("root")
775    );
776    assert_eq!(tree.get_node_by_path(["test"], false), None);
777  }
778
779  // this tests a couple of queries on this tree:
780  //
781  // root/       expanded     line:0
782  //   a/        collapsed    line:1
783  //     x/
784  //     y/
785  //   b/        expanded     line:2
786  //     z/
787  //   c/
788  #[test]
789  fn get_node_by_path_with_children() {
790    let tree = Tree::from_encoding(encoding::Tree {
791      version: Version::default(),
792      ty: TreeType::Root,
793      node: encoding::Node::new_by_expand_state(
794        "root",
795        true,
796        vec![
797          encoding::Node::new_by_expand_state(
798            "a",
799            false,
800            vec![
801              encoding::Node::new_by_expand_state("x", false, vec![]),
802              encoding::Node::new_by_expand_state("y", false, vec![]),
803            ],
804          ),
805          encoding::Node::new_by_expand_state(
806            "b",
807            true,
808            vec![encoding::Node::new_by_expand_state("z", false, vec![])],
809          ),
810          encoding::Node::new_by_expand_state("c", false, vec![]),
811        ],
812      ),
813    });
814
815    assert_eq!(
816      tree
817        .get_node_by_line(0)
818        .as_ref()
819        .map(|node| node.inner.borrow())
820        .as_ref()
821        .map(|node| node.name.as_str()),
822      Some("root")
823    );
824    assert_eq!(
825      tree
826        .get_node_by_path(["a"], false)
827        .as_ref()
828        .map(|node| node.inner.borrow())
829        .as_ref()
830        .map(|node| node.name.as_str()),
831      Some("a")
832    );
833    assert_eq!(
834      tree
835        .get_node_by_path(["a", "x"], false)
836        .as_ref()
837        .map(|node| node.inner.borrow())
838        .as_ref()
839        .map(|node| node.name.as_str()),
840      Some("x")
841    );
842    assert_eq!(
843      tree
844        .get_node_by_path(["a", "y"], false)
845        .as_ref()
846        .map(|node| node.inner.borrow())
847        .as_ref()
848        .map(|node| node.name.as_str()),
849      Some("y")
850    );
851    assert_eq!(
852      tree
853        .get_node_by_path(["b"], false)
854        .as_ref()
855        .map(|node| node.inner.borrow())
856        .as_ref()
857        .map(|node| node.name.as_str()),
858      Some("b")
859    );
860    assert_eq!(
861      tree
862        .get_node_by_path(["b", "z"], false)
863        .as_ref()
864        .map(|node| node.inner.borrow())
865        .as_ref()
866        .map(|node| node.name.as_str()),
867      Some("z")
868    );
869    assert_eq!(
870      tree
871        .get_node_by_path(["c"], false)
872        .as_ref()
873        .map(|node| node.inner.borrow())
874        .as_ref()
875        .map(|node| node.name.as_str()),
876      Some("c")
877    );
878  }
879
880  #[test]
881  fn get_index_from_parent() {
882    let tree = Tree::from_encoding(encoding::Tree {
883      version: Version::default(),
884      ty: TreeType::Root,
885      node: encoding::Node::new_by_expand_state(
886        "root",
887        true,
888        vec![
889          encoding::Node::new_by_expand_state(
890            "a",
891            false,
892            vec![
893              encoding::Node::new_by_expand_state("x", false, vec![]),
894              encoding::Node::new_by_expand_state("y", false, vec![]),
895            ],
896          ),
897          encoding::Node::new_by_expand_state(
898            "b",
899            true,
900            vec![encoding::Node::new_by_expand_state("z", false, vec![])],
901          ),
902          encoding::Node::new_by_expand_state("c", false, vec![]),
903        ],
904      ),
905    });
906
907    assert!(matches!(
908      tree
909        .get_node_by_path(["a", "x"], false)
910        .unwrap()
911        .get_index_from_parent(),
912      Ok(0)
913    ));
914    assert!(matches!(
915      tree
916        .get_node_by_path(["a", "y"], false)
917        .unwrap()
918        .get_index_from_parent(),
919      Ok(1)
920    ));
921  }
922
923  #[test]
924  fn insert() {
925    let tree = Tree::new("root", "");
926    let node = tree.get_node_by_line(0).unwrap();
927
928    node.insert_bottom(Node::new("x", ""));
929    node.insert_bottom(Node::new("y", ""));
930    node.insert_bottom(Node::new("z", ""));
931    node.insert_top(Node::new("c", ""));
932    node.insert_top(Node::new("b", ""));
933    node.insert_top(Node::new("a", ""));
934
935    tree
936      .get_node_by_path(["c"], false)
937      .unwrap()
938      .insert_after(Node::new("d", ""))
939      .unwrap();
940
941    tree
942      .get_node_by_path(["x"], false)
943      .unwrap()
944      .insert_before(Node::new("w", ""))
945      .unwrap();
946
947    assert!(matches!(
948      tree
949        .get_node_by_path(["a"], false)
950        .unwrap()
951        .get_index_from_parent(),
952      Ok(0)
953    ));
954    assert!(matches!(
955      tree
956        .get_node_by_path(["b"], false)
957        .unwrap()
958        .get_index_from_parent(),
959      Ok(1)
960    ));
961    assert!(matches!(
962      tree
963        .get_node_by_path(["c"], false)
964        .unwrap()
965        .get_index_from_parent(),
966      Ok(2)
967    ));
968    assert!(matches!(
969      tree
970        .get_node_by_path(["d"], false)
971        .unwrap()
972        .get_index_from_parent(),
973      Ok(3)
974    ));
975    assert!(matches!(
976      tree
977        .get_node_by_path(["w"], false)
978        .unwrap()
979        .get_index_from_parent(),
980      Ok(4)
981    ));
982    assert!(matches!(
983      tree
984        .get_node_by_path(["x"], false)
985        .unwrap()
986        .get_index_from_parent(),
987      Ok(5)
988    ));
989    assert!(matches!(
990      tree
991        .get_node_by_path(["y"], false)
992        .unwrap()
993        .get_index_from_parent(),
994      Ok(6)
995    ));
996    assert!(matches!(
997      tree
998        .get_node_by_path(["z"], false)
999        .unwrap()
1000        .get_index_from_parent(),
1001      Ok(7)
1002    ));
1003  }
1004
1005  #[test]
1006  fn delete() {
1007    let tree = Tree::new("root", "");
1008    let node = tree.get_node_by_line(0).unwrap();
1009
1010    node.insert_bottom(Node::new("x", ""));
1011    node.insert_bottom(Node::new("y", ""));
1012
1013    let x = tree.get_node_by_path(["x"], false).unwrap();
1014    x.insert_bottom(Node::new("a", ""));
1015    x.insert_bottom(Node::new("b", ""));
1016    x.insert_bottom(Node::new("c", ""));
1017
1018    let b = tree.get_node_by_path(["x", "b"], false).unwrap();
1019    x.delete(b).unwrap();
1020
1021    assert_eq!(tree.get_node_by_path(["x", "b"], false), None);
1022  }
1023
1024  #[test]
1025  fn select_move() {
1026    let tree = Tree::new("root", "");
1027    let node = tree.get_node_by_line(0).unwrap();
1028
1029    node.insert_bottom(Node::new("x", ""));
1030    node.insert_bottom(Node::new("y", ""));
1031    node.insert_bottom(Node::new("z", ""));
1032    node.insert_top(Node::new("c", ""));
1033    node.insert_top(Node::new("b", ""));
1034    node.insert_top(Node::new("a", ""));
1035
1036    let a = tree.get_node_by_path(["a"], false).unwrap();
1037    let b = tree.get_node_by_path(["b"], false).unwrap();
1038    let c = tree.get_node_by_path(["c"], false).unwrap();
1039    let x = tree.get_node_by_path(["x"], false).unwrap();
1040    let y = tree.get_node_by_path(["y"], false).unwrap();
1041    let z = tree.get_node_by_path(["z"], false).unwrap();
1042
1043    a.move_bottom(x.clone()).unwrap();
1044    a.move_top(y).unwrap();
1045    x.move_after(z.clone()).unwrap();
1046    z.move_before(b).unwrap();
1047    node.move_bottom(c).unwrap();
1048
1049    assert!(matches!(
1050      tree
1051        .get_node_by_path(["a", "y"], false)
1052        .unwrap()
1053        .get_index_from_parent(),
1054      Ok(0)
1055    ));
1056    assert!(matches!(
1057      tree
1058        .get_node_by_path(["a", "x"], false)
1059        .unwrap()
1060        .get_index_from_parent(),
1061      Ok(1)
1062    ));
1063    assert!(matches!(
1064      tree
1065        .get_node_by_path(["a", "b"], false)
1066        .unwrap()
1067        .get_index_from_parent(),
1068      Ok(2)
1069    ));
1070    assert!(matches!(
1071      tree
1072        .get_node_by_path(["a", "z"], false)
1073        .unwrap()
1074        .get_index_from_parent(),
1075      Ok(3)
1076    ));
1077    assert!(matches!(
1078      tree
1079        .get_node_by_path(["c"], false)
1080        .unwrap()
1081        .get_index_from_parent(),
1082      Ok(1)
1083    ));
1084  }
1085
1086  #[test]
1087  fn test_paths() {
1088    let tree = Tree::new("root", "");
1089    let node = tree.get_node_by_line(0).unwrap();
1090
1091    node.insert_bottom(Node::new("x", ""));
1092    node.insert_bottom(Node::new("y", ""));
1093
1094    let x = tree.get_node_by_path(["x"], false).unwrap();
1095    x.insert_bottom(Node::new("a", ""));
1096    x.insert_bottom(Node::new("b", ""));
1097    x.insert_bottom(Node::new("c", ""));
1098
1099    assert_eq!(
1100      node.paths("", NodeFilter::Always),
1101      vec!["", "/x", "/x/a", "/x/b", "/x/c", "/y"],
1102    );
1103  }
1104
1105  #[test]
1106  fn data() {
1107    let node = Node::new("test", "");
1108
1109    assert_eq!(node.data(), None);
1110
1111    assert!(matches!(
1112      node.set_data(NodeData::file("/tmp/foo.md")),
1113      Ok(())
1114    ));
1115    assert_eq!(node.data(), Some(NodeData::file("/tmp/foo.md")));
1116
1117    assert!(matches!(
1118      node.set_data(NodeData::file("/tmp/bar.rs")),
1119      Err(NodeError::FileDataAlreadyExists)
1120    ));
1121    assert_eq!(node.data(), Some(NodeData::file("/tmp/foo.md")));
1122
1123    assert!(matches!(
1124      node.set_data(NodeData::link("https://foo.bar")),
1125      Err(NodeError::MismatchDataType)
1126    ));
1127  }
1128}