syntree

Struct Tree

Source
pub struct Tree<T, F>
where T: Copy, F: Flavor,
{ /* private fields */ }
Expand description

A syntax tree.

A tree is constructed through a Builder or by modifying an existing tree through a ChangeSet.

§Type parameters and bounds

The three type parameters of the tree determines the following properties:

  • T is the data stored in the tree.
  • I determines the numerical bounds of spans stored in the tree through the Index trait, if set to Empty the tree does not store any spans.
  • W determines the bounds of pointers in the tree through the Width trait, this decides how many elements that can be stored in the tree.

To use the default values, use the Builder::new constructor.

Implementations§

Source§

impl<T, F> Tree<T, F>
where T: Copy, F: Flavor,

Source

pub const fn span(&self) -> &Span<F::Index>

Get the span of the current node. The span of a node is the complete span of all its children.

§Examples
use syntree::Span;

let tree = syntree::tree! {
    "root" => {
        "number" => {
            ("lit", 5)
        },
        "ident" => {
            ("lit", 3)
        }
    },
    "root2" => {
        ("whitespace", 5)
    }
};

assert_eq!(tree.span(), Span::new(0, 13));
Source

pub fn len(&self) -> usize

The total number of elements in the tree.

§Examples
let mut tree: syntree::Builder<()> = syntree::Builder::new();
let tree = tree.build()?;

assert_eq!(tree.len(), 0);

let mut tree = syntree::tree! {
    "root" => {
        "child" => {
            ("token", 2)
        },
        ("whitespace", 1),
        "child2" => {}
    }
};

assert_eq!(tree.len(), 5);
Source

pub fn is_empty(&self) -> bool

Check if the current tree is empty. In that it doesn’t have any childrens at the root of the tree.

§Examples
let mut tree: syntree::Builder<()> = syntree::Builder::new();
let tree = tree.build()?;
assert!(tree.is_empty());
Source

pub fn capacity(&self) -> usize

Get the capacity of the tree.

§Examples
let mut tree: syntree::Builder<()> = syntree::Builder::new();
let tree = tree.build()?;

assert_eq!(tree.capacity(), 0);

let mut tree = syntree::tree! {
    "root" => {
        "child" => {
            ("token", 2)
        },
        ("whitespace", 1),
        "child2" => {}
    }
};

assert!(tree.capacity() >= 5);
Source

pub fn children(&self) -> Children<'_, T, F>

Get all root nodes in the tree.

See Children for documentation.

Source

pub fn walk(&self) -> Walk<'_, T, F>

Walk the tree forwards in a depth-first fashion visiting every node once.

See Walk for documentation.

Source

pub fn walk_events(&self) -> WalkEvents<'_, T, F>

Walk the tree forwards in a depth-first fashion emitting events indicating how the tree is being traversed.

See WalkEvents for documentation.

Source

pub fn first(&self) -> Option<Node<'_, T, F>>

Get the first child node in the tree.

§Examples
let tree = syntree::tree! {
    "root" => {},
    "root2" => {}
};

let root = tree.first().ok_or("missing root")?;
assert_eq!(root.value(), "root");
Source

pub fn last(&self) -> Option<Node<'_, T, F>>

Get the last child node in the tree.

§Examples
let tree = syntree::tree! {
    "root" => {},
    "root2" => {}
};

let root = tree.last().ok_or("missing root")?;
assert_eq!(root.value(), "root2");
Source

pub fn get(&self, id: F::Pointer) -> Option<Node<'_, T, F>>

Get the ndoe at the given index.

Note that an id might be re-used across different trees. This behavior is never unsafe, but is not well-defined.

§Examples
let tree = syntree::tree! {
    "root" => {
        "number" => {
            ("lit", 5)
        },
        "ident" => {
            ("lit", 3)
        }
    },
    "root2" => {
        ("whitespace", 5)
    }
};

let node = tree.first().and_then(|n| n.last()).ok_or("missing ident")?;
assert_eq!(node.value(), "ident");

let id = node.id();
let node = tree.get(id).ok_or("missing ident")?;
assert_eq!(node.value(), "ident");
Source

pub fn range(&self) -> Range<usize>

Access the Span of the node as a Range.

§Examples
let tree = syntree::tree! {
    "root" => {
        "number" => {
            ("lit", 5)
        },
        "ident" => {
            ("lit", 3)
        }
    },
    "root2" => {
        ("whitespace", 5)
    }
};

assert_eq!(tree.range(), 0..13);
Source

pub fn node_with_range(&self, span: Range<usize>) -> Option<Node<'_, T, F>>

Query for the node that matches the given range.

This query finds the node which contains the entirety of the given Range.

§Examples
let tree = syntree::tree! {
    "root" => {
        "child1" => {
            ("token1", 3)
        },
        "child2" => {
            "nested1" => {
                ("token1", 4),
            },
            ("token4", 1),
        },
        "child3" => {
            ("token5", 5)
        }
    },
    "root2" => {}
};

let node = tree.node_with_range(0..0).ok_or("missing 0")?;
assert_eq!(node.value(), "child1");

let node = tree.node_with_range(0..3).ok_or("missing 0")?;
assert_eq!(node.value(), "child1");

let node = tree.node_with_range(3..3).ok_or("missing 3")?;
assert_eq!(node.value(), "nested1");

let node = tree.node_with_range(3..7).ok_or("missing 3..7")?;
assert_eq!(node.value(), "nested1");

let node = tree.node_with_range(7..7).ok_or("missing 7")?;
assert_eq!(node.value(), "child2");

let node = tree.node_with_range(7..8).ok_or("missing 7..8")?;
assert_eq!(node.value(), "child2");

let node = tree.node_with_range(8..8).ok_or("missing 8")?;
assert_eq!(node.value(), "child3");

let node = tree.node_with_range(8..13).ok_or("missing 9")?;
assert_eq!(node.value(), "child3");

let node = tree.node_with_range(2..4).ok_or("missing 2..4")?;
assert_eq!(node.value(), "root");

Range queries work as expected with checkpoints:

let mut tree = syntree::Builder::new();

let c = tree.checkpoint()?;
tree.open("child")?;
tree.token("lit", 3)?;
tree.close()?;
tree.close_at(&c, "root")?;
tree.token("sibling", 3)?;

let tree = tree.build()?;

let child = tree.node_with_range(0..3).ok_or("missing at 0..3")?;
assert_eq!(child.value(), "child");
Source

pub fn node_with_span(&self, span: Span<F::Index>) -> Option<Node<'_, T, F>>

Query the tree for the first node which encapsulates the whole span.

This query finds the node which contains the entirety of the given Span.

§Examples
use syntree::Span;

let tree = syntree::tree! {
    "root" => {
        "child1" => {
            ("token1", 3)
        },
        "child2" => {
            "nested1" => {
                ("token1", 4),
            },
            ("token4", 1),
        },
        "child3" => {
            ("token5", 5)
        }
    },
    "root2" => {}
};

let node = tree.node_with_span(Span::point(0)).ok_or("missing 0")?;
assert_eq!(node.value(), "child1");

let node = tree.node_with_span(Span::new(0, 3)).ok_or("missing 0")?;
assert_eq!(node.value(), "child1");

let node = tree.node_with_span(Span::point(3)).ok_or("missing 3")?;
assert_eq!(node.value(), "nested1");

let node = tree.node_with_span(Span::new(3, 7)).ok_or("missing 3..7")?;
assert_eq!(node.value(), "nested1");

let node = tree.node_with_span(Span::point(7)).ok_or("missing 7")?;
assert_eq!(node.value(), "child2");

let node = tree.node_with_span(Span::new(7, 8)).ok_or("missing 7..8")?;
assert_eq!(node.value(), "child2");

let node = tree.node_with_span(Span::point(8)).ok_or("missing 8")?;
assert_eq!(node.value(), "child3");

let node = tree.node_with_span(Span::new(8, 13)).ok_or("missing 9")?;
assert_eq!(node.value(), "child3");

let node = tree.node_with_span(Span::new(2, 4)).ok_or("missing 2..4")?;
assert_eq!(node.value(), "root");

Range queries work as expected with checkpoints:

use syntree::{Span, Builder};

let mut tree = Builder::new();

let c = tree.checkpoint()?;

tree.open("child1")?;
tree.token("lit", 3)?;
tree.close()?;

tree.open("child2")?;
tree.token("lit", 2)?;
tree.close()?;

tree.close_at(&c, "root")?;

let tree = tree.build()?;

let child = tree.node_with_span(Span::point(0)).ok_or("missing at point 5")?;
assert_eq!(child.value(), "child1");

let child = tree.node_with_span(Span::new(0, 3)).ok_or("missing at 0..3")?;
assert_eq!(child.value(), "child1");

let child = tree.node_with_span(Span::new(3, 5)).ok_or("missing at 3..5")?;
assert_eq!(child.value(), "child2");

let child = tree.node_with_span(Span::new(4, 5)).ok_or("missing at 4..5")?;
assert_eq!(child.value(), "child2");

let child = tree.node_with_span(Span::new(3, 4)).ok_or("missing at 3..4")?;
assert_eq!(child.value(), "child2");

let child = tree.node_with_span(Span::point(3)).ok_or("missing at point 5")?;
assert_eq!(child.value(), "child2");

let child = tree.node_with_span(Span::new(2, 5)).ok_or("missing at 2..5")?;
assert_eq!(child.value(), "root");

Trait Implementations§

Source§

impl<T, F> Clone for Tree<T, F>
where T: Copy, F: Flavor<Indexes: Clone, Width: Width<Pointer: Clone>>, F::Storage<Links<T, F::Index, F::Pointer>>: Clone,

Source§

fn clone(&self) -> Self

Returns a copy of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T, F> Debug for Tree<T, F>
where T: Copy + Debug, F: Flavor<Index: Debug>,

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<T, F> Default for Tree<T, F>
where T: Copy, F: Flavor,

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<T, A, B> PartialEq<Tree<T, A>> for Tree<T, B>
where T: Copy + PartialEq, A: Flavor, B: Flavor<Index: PartialEq<A::Index>>,

Source§

fn eq(&self, other: &Tree<T, A>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<T, F> Eq for Tree<T, F>
where T: Copy + Eq, F: Flavor<Index: Eq>,

Auto Trait Implementations§

§

impl<T, F> Freeze for Tree<T, F>
where <F as Flavor>::Storage<Links<T, <F as Flavor>::Index, <F as Flavor>::Pointer>>: Freeze, <F as Flavor>::Indexes: Freeze, <F as Flavor>::Index: Freeze, <F as Flavor>::Pointer: Freeze,

§

impl<T, F> RefUnwindSafe for Tree<T, F>
where <F as Flavor>::Storage<Links<T, <F as Flavor>::Index, <F as Flavor>::Pointer>>: RefUnwindSafe, <F as Flavor>::Indexes: RefUnwindSafe, <F as Flavor>::Index: RefUnwindSafe, <F as Flavor>::Pointer: RefUnwindSafe,

§

impl<T, F> Send for Tree<T, F>
where <F as Flavor>::Storage<Links<T, <F as Flavor>::Index, <F as Flavor>::Pointer>>: Send, <F as Flavor>::Indexes: Send, <F as Flavor>::Index: Send, <F as Flavor>::Pointer: Send,

§

impl<T, F> Sync for Tree<T, F>
where <F as Flavor>::Storage<Links<T, <F as Flavor>::Index, <F as Flavor>::Pointer>>: Sync, <F as Flavor>::Indexes: Sync, <F as Flavor>::Index: Sync, <F as Flavor>::Pointer: Sync,

§

impl<T, F> Unpin for Tree<T, F>
where <F as Flavor>::Storage<Links<T, <F as Flavor>::Index, <F as Flavor>::Pointer>>: Unpin, <F as Flavor>::Indexes: Unpin, <F as Flavor>::Index: Unpin, <F as Flavor>::Pointer: Unpin,

§

impl<T, F> UnwindSafe for Tree<T, F>
where <F as Flavor>::Storage<Links<T, <F as Flavor>::Index, <F as Flavor>::Pointer>>: UnwindSafe, <F as Flavor>::Indexes: UnwindSafe, <F as Flavor>::Index: UnwindSafe, <F as Flavor>::Pointer: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.