Module dtab::nametree [] [src]

Finagle/linkerd Name Trees.

This implementation is based loosely on Finagle's Scala implementation.

NameTrees can be parsed from strings; or they may be constructed programmatically using a set of operators. These operators provide a type-safe DSL for constructing correct NameTrees.

Examples

These examples are taken from linkerd's documentation on dtabs.

Suppose we had the simple dtab

/iceCreamStore => /smitten;

We could construct the corresponding Dentry using the following Rust expression:

use dtab::NameTree;

let dentry = NameTree::from("/iceCreamStore") >> "/smitten";
assert_eq!("/iceCreamStore => /smitten;", &dentry.to_string());

Take note of the following:

  • The right hand side of a NameTree operator must be of the type NameTree<T>, but the left hand side may be of any type R: convert::Into<NameTree<T>>, due to Rust's trait implementation rules. This means that we must explicitly call NameTree::from for the first path in the tree, but we can then use string literals for every other element, as NameTree<String> implements convert::From<&str>.
  • The >> operator is used in place of => to construct a Dentry. => is a reserved word in Rust, but >> is an overridable operator.

The | operator can be used to programmatically construct alternation expressions. For example:

/iceCreamStore => /humphrys | /smitten;

becomes

use dtab::NameTree;

let dentry = NameTree::from("/iceCreamStore") >>
             (NameTree::from("/humphrys") | "/smitten");
assert_eq!("/iceCreamStore => /humphrys | /smitten;", &dentry.to_string());

These alternation expressions can have any number of alternates, as in:

use dtab::NameTree;

let dest = NameTree::from("/humphrys") | "/smitten" | "/birite"
                  | "/three-twins";
let dentry = NameTree::from("/iceCreamStore") >> dest;
assert_eq!(
  "/iceCreamStore => /humphrys | /smitten | /birite | /three-twins;"
, &dentry.to_string()
);

Union expressions can be constructed using the & operator:

use dtab::NameTree;

let dest = NameTree::from("/smitten") & "/humphrys";
let dentry = NameTree::from("/iceCreamStore") >> dest;

assert_eq!( "/iceCreamStore => 0.5 * /smitten & 0.5 * /humphrys;"
           , &dentry.to_string());

Note that if no weight is supplied, the value of [DEFAULT_WEIGHT], 0.5, will be used.

Weighted unions can be constructed using the * operator:

use dtab::NameTree;
use dtab::nametree::W;

let dest = W(0.7) * "/smitten" & W(0.3) * "/humphrys";
let dentry = NameTree::from("/iceCreamStore") >> dest;
assert_eq!( "/iceCreamStore => 0.7 * /smitten & 0.3 * /humphrys;"
           , &dentry.to_string());

W() is a newtype used to allow the implementation of custom operators on f64. It's only used for constructing weighted NameTree expressions. The name W was chosen to keep the NameTree DSL from becoming too wordy.

Finally, the strings "~", "!", and "$" will convert into the negation, failure, and empty NameTree nodes, rather than leaf nodes:

use dtab::NameTree;

let dentry = NameTree::from("/iceCreamStore") >>
             (NameTree::from("~") | "/smitten");
assert_eq!( "/iceCreamStore => ~ | /smitten;"
           , &dentry.to_string());

let dentry = NameTree::from("/iceCreamStore") >>
             (NameTree::from("/smitten") | "!");
assert_eq!( "/iceCreamStore => /smitten | !;"
           , &dentry.to_string());

Note that this only works when the leaf type of the NameTree is String.

The NameTree variants Neg, Fail, and Empty can also be used explictly:

use dtab::NameTree;

let dentry = NameTree::from("/iceCreamStore") >>
            (NameTree::Neg | "/smitten");
assert_eq!( "/iceCreamStore => ~ | /smitten;"
           , &dentry.to_string());

let dentry = NameTree::from("/iceCreamStore") >>
             (NameTree::from("/smitten") | NameTree::Fail);
assert_eq!( "/iceCreamStore => /smitten | !;"
           , &dentry.to_string());

Structs

W
Weighted

Enums

NameTree

Name trees represent a composite name whose interpretation is subject to Finagle's interpretation rules

Constants

DEFAULT_WEIGHT

Functions

serialize