Ramify

Trait Ramify 

Source
pub trait Ramify<V> {
    // Required methods
    fn children(&mut self, vtx: V) -> impl IntoIterator<Item = V>;
    fn get_key(&self, vtx: &V) -> impl Ord;
    fn marker(&self, vtx: &V) -> char;

    // Provided method
    fn annotation<B: Write>(&self, vtx: &V, buf: B) -> Result { ... }
}
Expand description

A trait representing hierarchical data structures with efficient iteration of children.

For a version of this trait in which iteration of children might fail, see TryRamify.

Also see the Generator documentation for more information, particularly concerning the sequence of method calls and resource mangement.

Required Methods§

Source

fn children(&mut self, vtx: V) -> impl IntoIterator<Item = V>

Iterate over the children of the vertex.

This method is called exactly once for each vertex immediately before writing the corresponding branch diagram row.

§Iteration order

The iteration order is used to determine the horizontal order in which the vertices are drawn in the tree. This need not correspond to the precise column in which the node is actually drawn.

The below diagram shows the impact of various orders on how the nodes are laid out, for a node with key 0, which has children with keys 1 2 3 iterated in various orders.

123  132  213  231  312  321

0    0    0    0    0    0
├╮   ├╮   ├┬╮  ├╮   ├┬╮  ├╮
1│   1│   │1│  │1   │1│  │1
╭┤   ╭┤   2╭╯  ├╮   │ 2  ├╮
2│   │2    3   2│   3    │2
 3   3          3        3

Iterating in sorted order (either increasing or decreasing) or otherwise guaranteeing that the minimal element is first or last tends to produce narrower trees since this avoids 3-way forks.

Source

fn get_key(&self, vtx: &V) -> impl Ord

Get the key associated with a vertex.

This key is used for the vertical render order; that is, to decide which vertex should be rendered next. This is different than the iteration order of the children. See the documentation for Ramify::children to compare.

The active vertices are passed to Iterator::min_by_key when deciding which vertex should be rendered next on each iteration. In particular, the first element is returned if several elements are equally minimum.

The key is used ephemerally for sorting purposes and is not stored within the branch diagram. In particular, this method could be called many times for a given vertex.

§Key order

The keys are drawn in increasing order. Use Reverse or a custom Ord implementation if the vertices in your tree should be arranged in decreasing order.

In many standard use-cases, the children of a vertex are greater than the vertex itself. However, failing to guarantee this will not corrupt the branch diagram. The next vertex which is drawn is simply the minimal vertex out of the active vertices (the vertices vertices with an immediate parent already drawn to the diagram).

Source

fn marker(&self, vtx: &V) -> char

The vertex marker in the branch diagram.

The marker is the character written inside the branch diagram. In the below diagrams, the vertex markers are the chars 0, 1, 2, and 3.

0
├┬╮
│1│
2╭╯
 3
§Char width

This should be a char with width exactly 1 when displayed to the terminal. Other characters, such as control characters or double-width characters (mainly those described in Unicode Annex #11) will corrupt the tree drawing.

Here are some characters which might be useful:

  • * (\u{002a})
  • (\u{25ca})
  • (\u{2715})
  • (\u{25c8})
  • (\u{25c9})

Provided Methods§

Source

fn annotation<B: Write>(&self, vtx: &V, buf: B) -> Result

An annotation to write alongside a vertex.

This will be called exactly once per vertex. The lines of the annotations are written sequentially, with the first line written on the same line as the vertex with which it is associated. The default implementation does not write an annotation.

§Implementation details

Implementations of this method should write the annotation directly into the fmt::Write buffer, including newlines for annotations spanning multiple lines. The annotations are automatically line-broken and aligned with the branch diagram when rendered.

Like the standard library implementation of str::lines, the final trailing newline is optional and ignored if present. If you want extra space between consecutive annotations, it is best to use the row_padding option of the Config struct.

§Example

The presence of the annotation influences the drawing of the tree, in that subsequent vertices are delayed in order to make space for the entire annotation followed by the margin.

0   An annotation occupying two lines
╰╮  followed by one line of margin
╭┼╮
│1│ An annotation with one line and no margin.
2╭╯
 3  The annotation for vertex 2 is empty.

Dyn Compatibility§

This trait is not dyn compatible.

In older versions of Rust, dyn compatibility was called "object safety", so this trait is not object safe.

Implementors§