Module dtab::nametree
[−]
[src]
Finagle/linkerd Name Trees.
This implementation is based loosely on Finagle's Scala implementation.
NameTree
s 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 NameTree
s.
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 typeNameTree<T>
, but the left hand side may be of any typeR: convert::Into<NameTree<T>>
, due to Rust's trait implementation rules. This means that we must explicitly callNameTree::from
for the first path in the tree, but we can then use string literals for every other element, asNameTree<String>
implementsconvert::From<&str>
. - The
>>
operator is used in place of=>
to construct aDentry
.=>
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 |