diff --git a/book/.nojekyll b/book/.nojekyll new file mode 100644 index 00000000..f1731109 --- /dev/null +++ b/book/.nojekyll @@ -0,0 +1 @@ +This file makes sure that Github Pages doesn't process mdBook's output. diff --git a/book/01-01-installation.html b/book/01-01-installation.html new file mode 100644 index 00000000..2d373898 --- /dev/null +++ b/book/01-01-installation.html @@ -0,0 +1,255 @@ + + + + + + Installation - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Installation

+

Rust

+

The first thing we'll need to do is install Rust. We'll be using a tool called +rustup. On Unix/Linux like platforms, simply run the +following from your terminal. For other platforms see the rustup docs.

+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+
+

It may be necessary to restart your shell session after installing Rust.

+

x4c

+

Now we will install the x4c compiler using the rust cargo tool.

+
cargo install --git https://github.com/oxidecomputer/p4 x4c
+
+

You should now be able to run x4c.

+
x4c --help
+x4c 0.1
+
+USAGE:
+    x4c [OPTIONS] <FILENAME> [TARGET]
+
+ARGS:
+    <FILENAME>    File to compile
+    <TARGET>      What target to generate code for [default: rust] [possible values: rust,
+                  red-hawk, docs]
+
+OPTIONS:
+        --check          Just check code, do not compile
+    -h, --help           Print help information
+    -o, --out <OUT>      Filename to write generated code to [default: out.rs]
+        --show-ast       Show parsed abstract syntax tree
+        --show-hlir      Show high-level intermediate representation info
+        --show-pre       Show parsed preprocessor info
+        --show-tokens    Show parsed lexical tokens
+    -V, --version        Print version information
+
+

That's it! We're now ready to dive into P4 code.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/01-02-hello_world.html b/book/01-02-hello_world.html new file mode 100644 index 00000000..8227c7f8 --- /dev/null +++ b/book/01-02-hello_world.html @@ -0,0 +1,539 @@ + + + + + + Hello World - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Hello World

+

Let's start out our introduction of P4 with the obligatory hello world program.

+

Parsing

+

The first bit of programmable logic packets hit in a P4 program is a parser. +Parsers do the following.

+
    +
  1. Describe a state machine packet parsing.
  2. +
  3. Extract raw data into headers with typed fields.
  4. +
  5. Decide if a packet should be accepted or rejected based on parsed structure.
  6. +
+

In the code below, we can see that parsers are defined somewhat like functions +in general-purpose programming languages. They take a set of parameters and have +a curly-brace delimited block of code that acts over those parameters.

+

Each of the parameters has an optional direction that we see here as out or +inout, a type, and a name. We'll get to data types in the next section for now +let's focus on what this parser code is doing.

+

The parameters shown here are typical of what you will see for P4 parsers. The +exact set of parameters varies depending on ASIC the P4 code is being compiled +for. But in general, there will always need to be - a packet, set of headers to +extract packet data into and a bit of metadata about the packet that the ASIC +has collected.

+
parser parse (
+    packet_in pkt,
+    out headers_t headers,
+    inout ingress_metadata_t ingress,
+){
+    state start {
+        pkt.extract(headers.ethernet);
+        transition finish;
+    }
+
+    state finish {
+        transition accept;
+    }
+}
+
+

Parsers are made up of a set of states and transitions between those states. +Parsers must always include a start state. Our start state extracts an +Ethernet header from the incoming packet and places it in to the headers_t +parameter passed to the parser. We then transition to the finish state where +we simply transition to the implicit accept state. We could have just +transitioned to accept from start, but wanted to show transitions between +user-defined states in this example.

+

Transitioning to the accept state means that the packet will be passed to a +control block for further processing. Control blocks will be covered a few +sections from now. Parsers can also transition to the implicit reject state. +This means that the packet will be dropped and not go on to any further +processing.

+

Data Types

+

There are two primary data types in P4, struct and header types.

+

Structs

+

Structs in P4 are similar to structs you'll find in general purpose programming +languages such as C, Rust, and Go. They are containers for data with typed data +fields. They can contain basic data types, headers as well as other structs.

+

Let's take a look at the structs in use by our hello world program.

+

The first is a structure containing headers for our program to extract packet +data into. This headers_t structure is simple and only contains one header. +However, there may be an arbitrary number of headers in the struct. We'll +discuss headers in the next section.

+
struct headers_t {
+    ethernet_t ethernet;
+}
+
+

The next structure is a bit of metadata provided to our parser by the ASIC. In +our simple example this just includes the port that the packet came from. So if +our code is running on a four port switch, the port field would take on a +value between 0 and 3 depending on which port the packet came in on.

+
struct ingress_metadata_t {
+    bit<16> port;
+}
+
+

As the name suggests bit<16> is a 16-bit value. In P4 the bit<N> type +commonly represents unsigned integer values. We'll get more into the primitive +data types of P4 later.

+

Headers

+

Headers are the result of parsing packets. They are similar in nature to +structures with the following differences.

+
    +
  1. Headers may not contain headers.
  2. +
  3. Headers have a set of methods isValid(), setValid(), and setValid() +that provide a means for parsers and control blocks to coordinate on the +parsed structure of packets as they move through pipelines.
  4. +
+

Let's take a look at the ethernet_h header in our hello world example.

+
header ethernet_h {
+    bit<48> dst;
+    bit<48> src;
+    bit<16> ether_type;
+}
+
+

This header represents a layer-2 +Ethernet frame. +The leading octet is not present as this will be removed by most ASICs. What +remains is the MAC source and destination fields which are each 6 octets / 48 +bits and the ethertype which is 2 octets.

+

Note also that the payload is not included here. This is important. P4 programs +typically operate on packet headers and not packet payloads. In upcoming +examples we'll go over header stacks that include headers at higher layers like +IP, ICMP and TCP.

+

In the parsing code above, when pkt.extract(headers.ethernet) is called, the +values dst, src and ether_type are populated from packet data and the +method setValid() is implicitly called on the headers.ethernet header.

+

Control Blocks

+

Control blocks are where logic goes that decides what will happen to packets +that are parsed successfully. Similar to a parser block, control blocks look a +lot like functions from general purpose programming languages. The signature +(the number and type of arguments) for this control block is a bit different +than the parser block above.

+

The first argument hdr, is the output of the parser block. Note in the parser +signature there is a out headers_t headers parameter, and in this control +block there is a inout headers_t hdr parameter. The out direction in the +parser means that the parser writes to this parameter. The inout direction +in the control block means that the control both reads and writes to this +parameter.

+

The ingress_metadata_t parameter is the same parameter we saw in the parser +block. The egress_metadata_t is similar to ingress_metadata_t. However, +our code uses this parameter to inform the ASIC about how it should treat packets +on egress. This is in contrast to the ingress_metdata_t parameter that is used +by the ASIC to inform our program about details of the packet's ingress.

+
control ingress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+
+    action drop() { }
+
+    action forward(bit<16> port) {
+        egress.port = port;
+    }
+
+    table tbl {
+        key = {
+            ingress.port: exact;
+        }
+        actions = {
+            drop;
+            forward;
+        }
+        default_action = drop;
+        const entries = {
+            16w0 : forward(16w1);
+            16w1 : forward(16w0);
+        }
+    }
+
+    apply {
+        tbl.apply();
+    }
+
+}
+
+

Control blocks are made up of tables, actions and apply blocks. When packet +headers enter a control block, the apply block decides what tables to run the +parameter data through. Tables are described in terms if keys and actions. A +key is an ordered sequence of fields that can be extracted from any of the +control parameters. In the example above we are using the port field from the +ingress parameter to decide what to do with a packet. We are not even +investigating the packet headers at all! We can indeed use header fields in +keys, and an example of doing so will come later.

+

When a table is applied, and there is an entry in the table that matches the key +data, the action corresponding to that key is executed. In our example we have +pre-populated our table with two entries. The first entry says, if the ingress +port is 0, forward the packet to port 1. The second entry says if the ingress +port is 1, forward the packet to port 0. These odd looking prefixes on our +numbers are width specifiers. So 16w0 reads: the value 0 with a width of 16 +bits.

+

Every action that is specified in a table entry must be defined within the +control. In our example, the forward action is defined above. All this action +does is set the port field on the egress metadata to the provided value.

+

The example table also has a default action of drop. This action fires for all +invocations of the table over key data that has no matching entry. So for our +program, any packet coming from a port that is not 0 or 1 will be dropped.

+

The apply block is home to generic procedural code. In our example it's very +simple and only has an apply invocation for our table. However, arbitrary +logic can go in this block, we could even implement the logic of this control +without a table!

+
apply {
+    if (ingress.port == 16w0) {
+        egress.port = 16w1;
+    }
+    if (ingress.port == 16w1) {
+        egress.port = 16w0;
+    }
+}
+
+

Which then begs the question, why have a special table construct at all. Why not +just program everything using logical primitives? Or let programmers define +their own data structures like general purpose programming languages do?

+

Setting the performance arguments aside for the moment, there is something +mechanically special about tables. They can be updated from outside the P4 +program. In the program above we have what are called constant entries defined +directly in the P4 program. This makes presenting a simple program like this +very straight forward, but it is not the way tables are typically populated. The +focus of P4 is on data plane programming e.g., given a packet from the wire what +do we do with it? I prime example of this is packet routing and forwarding.

+

Both routing and forwarding are typically implemented in terms of lookup tables. +Routing is commonly implemented by longest prefix matching on the destination +address of an IP packet and forwarding is commonly implemented by exact table +lookups on layer-2 MAC addresses. How are those lookup tables populated though. +There are various different answers there. Some common ones include routing +protocols like OSPF, or BGP. Address resolution protocols like ARP and NDP. Or +even more simple answers like an administrator statically adding a route to the +system.

+

All of these activities involve either a stateful protocol of some sort or +direct interaction with a user. Neither of those things is possible in the P4 +programming language. It's just about processing packets on the wire and the +mechanisms for keeping state between packets is extremely limited.

+

What P4 implementations do provide is a way for programs written in +general purpose programming languages that are capable of stateful +protocol implementation and user interaction - to modify the tables of a running +P4 program through a runtime API. We'll come back to runtime APIs soon. For now +the point is that the table abstraction allows P4 programs to remain focused on +simple, mostly-stateless packet processing tasks that can be implemented at high +packet rates and leave the problem of table management to the general purpose +programming languages that interact with P4 programs through shared table +manipulation.

+

Package

+

The final bit to show for our hello world program is a package instantiation. +A package is like a constructor function that takes a parser and a set of +control blocks. Packages are typically tied to the ASIC your P4 code will be +executing on. In the example below, we are passing our parser and single control +block to the SoftNPU package. Packages for more complex ASICs may take many +control blocks as arguments.

+
SoftNPU(
+    parse(),
+    ingress()
+) main;
+
+

Full Program

+

Putting it all together, we have a complete P4 hello world program as follows.

+
struct headers_t {
+    ethernet_h ethernet;
+}
+
+struct ingress_metadata_t {
+    bit<16> port;
+    bool drop;
+}
+
+struct egress_metadata_t {
+    bit<16> port;
+    bool drop;
+    bool broadcast;
+}
+
+header ethernet_h {
+    bit<48> dst;
+    bit<48> src;
+    bit<16> ether_type;
+}
+
+parser parse (
+    packet_in pkt,
+    out headers_t headers,
+    inout ingress_metadata_t ingress,
+){
+    state start {
+        pkt.extract(headers.ethernet);
+        transition finish;
+    }
+
+    state finish {
+        transition accept;
+    }
+}
+
+control ingress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+
+    action drop() { }
+
+    action forward(bit<16> port) {
+        egress.port = port;
+    }
+
+    table tbl {
+        key = {
+            ingress.port: exact;
+        }
+        actions = {
+            drop;
+            forward;
+        }
+        default_action = drop;
+        const entries = {
+            16w0 : forward(16w1);
+            16w1 : forward(16w0);
+        }
+    }
+
+    apply {
+        tbl.apply();
+    }
+
+}
+
+// We do not use an egress controller in this example, but one is required for
+// SoftNPU so just use an empty controller here.
+control egress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+
+}
+
+SoftNPU(
+    parse(),
+    ingress(),
+    egress(),
+) main;
+
+

This program will take any packet that has an Ethernet header showing up on port +0, send it out port 1, and vice versa. All other packets will be dropped.

+

In the next section we'll compile this program and run some packets through it!

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/01-03-compile_and_run.html b/book/01-03-compile_and_run.html new file mode 100644 index 00000000..c558e952 --- /dev/null +++ b/book/01-03-compile_and_run.html @@ -0,0 +1,344 @@ + + + + + + Compile and Run - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Compile and Run

+

In the previous section we put together a hello world P4 program. In this +section we run that program over a software ASIC called SoftNpu. One of the +capabilities of the x4c compiler is using P4 code directly from Rust code +and we'll be doing that in this example.

+

Below is a Rust program that imports the P4 code developed in the last section, +loads it onto a SoftNpu ASIC instance, and sends some packets through it. We'll +be looking at this program piece-by-piece in the remainder of this section.

+

All of the programs in this book are available as buildable programs in the +oxidecomputer/p4 repository in the +book/code directory.

+
use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+use tests::{expect_frames};
+
+p4_macro::use_p4!(p4 = "book/code/src/bin/hello-world.p4", pipeline_name = "hello");
+
+fn main() -> Result<(), anyhow::Error> {
+    let pipeline = main_pipeline::new(2);
+    let mut npu = SoftNpu::new(2, pipeline, false);
+    let phy1 = npu.phy(0);
+    let phy2 = npu.phy(1);
+
+    npu.run();
+
+    phy1.send(&[TxFrame::new(phy2.mac, 0, b"hello")])?;
+    expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b"hello")]);
+
+    phy2.send(&[TxFrame::new(phy1.mac, 0, b"world")])?;
+    expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b"world")]);
+
+    Ok(())
+}
+

The program starts with a few Rust imports.

+
use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+use tests::{expect_frames};
+

This first line is the SoftNpu implementation that lives in the test crate of +the oxidecomputer/p4 repository. The second is a helper macro that allows us +to make assertions about frames coming from a SoftNpu "physical" port (referred +to as a phy).

+

The next line is using the x4c compiler to translate P4 code into Rust code +and dumping that Rust code into our program. The macro literally expands into +the Rust code emitted by the compiler for the specified P4 source file.

+
p4_macro::use_p4!(p4 = "book/code/src/bin/hello-world.p4", pipeline_name = "hello");
+

The main artifact this produces is a Rust struct called main_pipeline which is used +in the code that comes next.

+
let pipeline = main_pipeline::new(2);
+let mut npu = SoftNpu::new(2, pipeline, false);
+let phy1 = npu.phy(0);
+let phy2 = npu.phy(1);
+

This code is instantiating a pipeline object that encapsulates the logic of our +P4 program. Then a SoftNpu ASIC is constructed with two ports and our pipeline +program. SoftNpu objects provide a phy method that takes a port index to get a +reference to a port that is attached to the ASIC. These port objects are used to +send and receive packets through the ASIC, which uses our compiled P4 code to +process those packets.

+

Next we run our program on the SoftNpu ASIC.

+
npu.run();
+

However, this does not actually do anything until we pass some packets through +it, so lets do that.

+
phy1.send(&[TxFrame::new(phy2.mac, 0, b"hello")])?;
+

This code transmits an Ethernet frame through the first port of the ASIC with a +payload value of "hello". The phy2.mac parameter of the TxFrame sets the +destination MAC address and the 0 for the second parameter is the ethertype +used in the outgoing Ethernet frame.

+

Based on the logic in our P4 program, we would expect this packet to come out +the second port. Let's test that.

+
expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b"hello")]);
+

This code reads a packet from the second ASIC port phy2 (blocking until there +is a packet available) and asserts the following.

+
    +
  • The Ethernet payload is the byte string "hello".
  • +
  • The source MAC address is that of phy1.
  • +
  • The ethertype is 0.
  • +
+

To complete the hello world program, we do the same thing in the opposite +direction. Sending the byte string "world" as an Ethernet payload into port 2 +and assert that it comes out port 1.

+
phy2.send(&[TxFrame::new(phy1.mac, 0, b"world")])?;
+expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b"world")]);
+

The expect_frames macro will also print payloads and the port they came from.

+

When we run this program we see the following.

+
$ cargo run --bin hello-world
+   Compiling x4c-book v0.1.0 (/home/ry/src/p4/book/code)
+    Finished dev [unoptimized + debuginfo] target(s) in 2.05s
+     Running `target/debug/hello-world`
+[phy2] hello
+[phy1] world
+
+

SoftNpu and Target x4c Use Cases.

+

The example above shows using x4c compiled code is a setting that is only +really useful for testing the logic of compiled pipelines and demonstrating how +P4 and x4c compiled pipelines work. This begs the question of what the target +use cases for x4c actually are. It also raises question, why build x4c in the +first place? Why not use the established reference compiler p4c and its +associated reference behavioral model bmv2?

+

A key difference between x4c and the p4c ecosystem is how compilation +and execution concerns are separated. x4c generates free-standing pipelines +that can be used by other code, p4c generates JSON that is interpreted and run +by bmv2.

+

The example above shows how the generation of free-standing runnable pipelines +can be used to test the logic of P4 programs in a lightweight way. We went from +P4 program source to actual packet processing using nothing but the Rust +compiler and package manager. The program is executable in an operating system +independent way and is a great way to get CI going for P4 programs.

+

The free-standing pipeline approach is not limited to self-contained use cases +with packets that are generated and consumed in-program. x4c generated code +conforms to a well defined +Pipeline +interface that can be used to run pipelines anywhere rustc compiled code can +run. Pipelines are even dynamically loadable through dlopen and the like.

+

The x4c authors have used x4c generated pipelines to create virtual ASICs +inside hypervisors that transit real traffic between virtual machines, as well +as P4 programs running inside zones/containers that implement NAT and tunnel +encap/decap capabilities. The mechanics of I/O are deliberately outside the +scope of x4c generated code. Whether you want to use DLPI, XDP, libpcap, +PF_RING, DPDK, etc., is up to you and the harness code you write around your +pipelines!

+

The win with x4c is flexibility. You can compile a free-standing P4 pipeline +and use that pipeline wherever you see fit. The near-term use for x4c focuses +on development and evaluation environments. If you are building a system around +P4 programmable components, but it's not realistic to buy all the +switches/routers/ASICs at the scale you need for testing/development, x4c is an +option. x4c is also a good option for running packets through your pipelines +in a lightweight way in CI.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/01-basics.html b/book/01-basics.html new file mode 100644 index 00000000..36418f84 --- /dev/null +++ b/book/01-basics.html @@ -0,0 +1,229 @@ + + + + + + The Basics - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

The Basics

+

This chapter will take you from zero to a simple hello-world program in P4. +This will include.

+
    +
  • Getting a Rust toolchain setup and installing the x4c compiler.
  • +
  • Compiling a P4 hello world program into a Rust program.
  • +
  • Writing a bit of Rust code to push packets through the our compiled P4 +pipelines.
  • +
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/02-01-vlan-switch.html b/book/02-01-vlan-switch.html new file mode 100644 index 00000000..6a8f1410 --- /dev/null +++ b/book/02-01-vlan-switch.html @@ -0,0 +1,632 @@ + + + + + + VLAN Switch - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

VLAN Switch

+

This example presents a simple VLAN switch program. This program allows a single +VLAN id (vid) to be set per port. Any packet arriving at a port with a vid +set must carry that vid in its Ethernet header or it will be dropped. We'll +refer to this as VLAN filtering. If a packet makes it past ingress filtering, +then the forwarding table of the switch is consulted to see what port to send +the packet out. We limit ourselves to a very simple switch here with a static +forwarding table. A MAC learning switch will be presented in a later example. +This switch also does not do flooding for unknown packets, it simply operates on +the lookup table it has. If an egress port is identified via a forwarding table +lookup, then egress VLAN filtering is applied. If the vid on the packet is +present on the egress port then the packet is forwarded out that port.

+

This example is comprised of two programs. A P4 data-plane program and a Rust +control-plane program.

+

P4 Data-Plane Program

+

Let's start by taking a look at the headers for the P4 program.

+
header ethernet_h {
+    bit<48> dst;
+    bit<48> src;
+    bit<16> ether_type;
+}
+
+header vlan_h {
+    bit<3> pcp;
+    bit<1> dei;
+    bit<12> vid;
+    bit<16> ether_type;
+}
+
+struct headers_t {
+    ethernet_h eth;
+    vlan_h vlan;
+}
+
+

An Ethernet frame is normally just 14 bytes with a 6 byte source and destination +plus a two byte ethertype. However, when VLAN tags are present the ethertype is +set to 0x8100 and a VLAN header follows. This header contains a 12-bit vid +as well as an ethertype for the header that follows.

+

A byte-oriented packet diagram shows how these two Ethernet frame variants line +up.

+
                     1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
++---------------------------+
+|    src    |    dst    |et |
++---------------------------+
++-----------------------------------+
+|    src    |    dst    |et |pdv|et |
++------------------------------------
+
+

The structure is always the same for the first 14 bytes. So we can take +advantage of that when parsing any type of Ethernet frame. Then we can use the +ethertype field to determine if we are looking at a regular Ethernet frame or a +VLAN-tagged Ethernet frame.

+
parser parse (
+    packet_in pkt,
+    out headers_t h,
+    inout ingress_metadata_t ingress,
+) {
+    state start {
+        pkt.extract(h.eth);
+        if (h.eth.ether_type == 16w0x8100) { transition vlan; } 
+        transition accept;
+    }
+    state vlan {
+        pkt.extract(h.vlan);
+        transition accept;
+    }
+}
+
+

This parser does exactly what we described above. First parse the first 14 bytes +of the packet as an Ethernet frame. Then conditionally parse the VLAN portion of +the Ethernet frame if the ethertype indicates we should do so. In a sense we can +think of the VLAN portion of the Ethernet frame as being it's own independent +header. We are keying our decisions based on the ethertype, just as we would for +layer 3 protocol headers.

+

Our VLAN switch P4 program is broken up into multiple control blocks. We'll +start with the top level control block and then dive into the control blocks it +calls into to implement the switch.

+
control ingress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+    vlan() vlan;
+    forward() fwd;
+    
+    apply {
+        bit<12> vid = 12w0;
+        if (hdr.vlan.isValid()) {
+            vid = hdr.vlan.vid;
+        }
+
+        // check vlan on ingress
+        bool vlan_ok = false;
+        vlan.apply(ingress.port, vid, vlan_ok);
+        if (vlan_ok == false) {
+            egress.drop = true;
+            return;
+        }
+
+        // apply switch forwarding logic
+        fwd.apply(hdr, egress);
+
+        // check vlan on egress
+        vlan.apply(egress.port, vid, vlan_ok);
+        if (vlan_ok == false) {
+            egress.drop = true;
+            return;
+        }
+    }
+}
+
+

The first thing that is happening in this program is the instantiation of a few +other control blocks.

+
vlan() vlan;
+forward() fwd;
+
+

We'll be using these control blocks to implement the VLAN filtering and switch +forwarding logic. For now let's take a look at the higher level packet +processing logic of the program in the apply block.

+

The first thing we do is start by assuming there is no vid by setting it to +zero. The if the VLAN header is valid we assign the vid from the packet header +to our local vid variable. The isValid header method returns true if +extract was called on that header. Recall from the parser code above, that +extract is only called on hdr.vlan if the ethertype on the Ethernet frame is +0x1800.

+
bit<12> vid = 12w0;
+if (hdr.vlan.isValid()) {
+    vid = hdr.vlan.vid;
+}
+
+

Next apply VLAN filtering logic. First an indicator variable vlan_ok is +initialized to false. Then we pass that indicator variable along with the port +the packet came in on and the vid we determined above to the VLAN control +block.

+
bool vlan_ok = false;
+vlan.apply(ingress.port, vid, vlan_ok);
+if (vlan_ok == false) {
+    egress.drop = true;
+    return;
+}
+
+

Let's take a look at the VLAN control block. The first thing to note here is the +direction of parameters. The port and vid parameters are in parameters, +meaning that the control block can only read from them. The match parameter is +an out parameter meaning the control block can only write to it. Consider this +in the context of the code above. There we are passing in the vlan_ok to the +control block with the expectation that the control block will modify the value +of the variable. The out direction of this control block parameter is what +makes that possible.

+
control vlan(
+    in bit<16> port,
+    in bit<12> vid,
+    out bool match,
+) {
+    action no_vid_for_port() {
+        match = true;
+    }
+
+    action filter(bit<12> port_vid) { 
+        if (port_vid == vid) { match = true; } 
+    }
+    
+    table port_vlan {
+        key             = { port: exact; }
+        actions         = { no_vid_for_port; filter; }
+        default_action  = no_vid_for_port;
+    }
+
+    apply { port_vlan.apply(); }
+}
+
+

Let's look at this control block starting from the table declaration. The +port_vlan table has the port id as the single key element. There are two +possible actions no_vid_for_port and filter. The no_vid_for_port fires +when there is no match for the port id. That action unconditionally sets +match to true. The logic here is that if there is no VLAN configure for a port +e.g., the port is not in the table, then there is no need to do any VLAN +filtering and just pass the packet along.

+

The filter action takes a single parameter port_vid. This value is populated +by the table value entry corresponding to the port key. There are no static +table entries in this P4 program, they are provided by a control plane program +which we'll get to in a bit. The filter logic tests if the port_vid that has +been configured by the control plane matches the vid on the packet. If the +test passes then match is set to true meaning the packet can continue +processing.

+

Popping back up to the top level control block. If vlan_ok was not set to +true in the vlan control block, then we drop the packet. Otherwise we +continue on to further processing - forwarding.

+

Here we are passing the entire header and egress metadata structures into the +fwd control block which is an instantiation of the forward control block +type.

+
fwd.apply(hdr, egress);
+
+

Lets take a look at the forward control block.

+
control forward(
+    inout headers_t hdr,
+    inout egress_metadata_t egress,
+) {
+    action drop() {}
+    action forward(bit<16> port) { egress.port = port; }
+
+    table fib {
+        key             = { hdr.eth.dst: exact; }
+        actions         = { drop; forward; }
+        default_action  = drop;
+    }
+
+    apply { fib.apply(); }
+}
+
+

This simple control block contains a table that maps Ethernet addresses to +ports. The single element key contains an Ethernet destination and the matching +action forward contains a single 16-bit port value. When the Ethernet +destination matches an entry in the table, the egress metadata destination for +the packet is set to the port id that has been set for that table entry.

+

Note that in this control block both parameters have an inout direction, +meaning the control block can both read from and write to these parameters. +Like the vlan control block above, there are no static entries here. Entries +for the table in this control block are filled in by a control-plane program.

+

Popping back up the stack to our top level control block, the remaining code we +have is the following.

+
vlan.apply(egress.port, vid, vlan_ok);
+if (vlan_ok == false) {
+    egress.drop = true;
+    return;
+}
+
+

This is pretty much the same as what we did at the beginning of the apply block. +Except this time, we are passing in the egress port instead of the ingress port. +We are checking the VLAN tags not only for the ingress port, but also for the +egress port.

+

You can find this program in it's entirety +here.

+

Rust Control-Plane Program

+

The main purpose of the Rust control plane program is to manage table entries in +the P4 program. In addition to table management, the program we'll be showing +here also instantiates and runs the P4 code over a virtual ASIC to demonstrate +the complete system working.

+

We'll start top down again. Here is the beginning of our Rust program.

+
use tests::expect_frames;
+use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+
+p4_macro::use_p4!(
+    p4 = "book/code/src/bin/vlan-switch.p4",
+    pipeline_name = "vlan_switch"
+);
+
+fn main() -> Result<(), anyhow::Error> {
+    let mut pipeline = main_pipeline::new(2);
+
+    let m1 = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33];
+    let m2 = [0x44, 0x44, 0x44, 0x44, 0x44, 0x44];
+
+    init_tables(&mut pipeline, m1, m2);
+    run_test(pipeline, m2)
+}
+

After imports, the first thing we are doing is calling the use_p4! macro. This +translates our P4 program into Rust and expands the use_p4! macro in place to +the generated Rust code. This results in the main_pipeline type that we see +instantiated in the first line of the main program. Then we define a few MAC +addresses that we'll get back to later. The remainder of the main code +performs the two functions described above. The init_tables function acts as a +control plane for our P4 code, setting up the VLAN and forwarding tables. The +run_test code executes our instantiated pipeline over a virtual ASIC, sends +some packets through it, and makes assertions about the results.

+

Control Plane Code

+

Let's jump into the control plane code.

+
fn init_tables(pipeline: &mut main_pipeline, m1: [u8;6], m2: [u8;6]) {
+    // add static forwarding entries
+    pipeline.add_ingress_fwd_fib_entry("forward", &m1, &0u16.to_be_bytes());
+    pipeline.add_ingress_fwd_fib_entry("forward", &m2, &1u16.to_be_bytes());
+
+    // port 0 vlan 47
+    pipeline.add_ingress_vlan_port_vlan_entry(
+        "filter",
+        0u16.to_be_bytes().as_ref(),
+        47u16.to_be_bytes().as_ref(),
+    );
+
+    // sanity check the table
+    let x = pipeline.get_ingress_vlan_port_vlan_entries();
+    println!("{:#?}", x);
+
+    // port 1 vlan 47
+    pipeline.add_ingress_vlan_port_vlan_entry(
+        "filter",
+        1u16.to_be_bytes().as_ref(),
+        47u16.to_be_bytes().as_ref(),
+    );
+
+}
+

The first thing that happens here is the forwarding tables are set up. We add +two entries one for each MAC address. The first MAC address maps to the first +port and the second MAC address maps to the second port.

+

We are using table modification methods from the Rust code that was generated +from our P4 code. A valid question is, how do I know what these are? There are +two ways.

+

Determine Based on P4 Code Structure

+

The naming is deterministic based on the structure of the p4 program. Table +modification functions follow the pattern +<operation>_<control_path>_<table_name>_entry. Where operation one of the +following.

+
    +
  • add
  • +
  • remove
  • +
  • get.
  • +
+

The control_path is based on the names of control instances starting from the +top level ingress controller. In our P4 program, the forwarding table is named +fwd so that is what we see in the function above. If there is a longer chain +of controller instances, the instance names are underscore separated. Finally +the table_name is the name of the table in the control block. This is how we +arrive at the method name above.

+
pipeline.add_fwd_fib_entry(...)
+

Use cargo doc

+

Alternatively you can just run cargo doc to have Cargo generate documentation +for your crate that contains the P4-generated Rust code. This will emit Rust +documentation that includes documentation for the generated code.

+

Now back to the control plane code above. You'll also notice that we are adding +key values and parameter values to the P4 tables as byte slices. At the time of +writing, x4c is not generating high-level table manipulation APIs so we have +to pass everything in as binary serialized data.

+

The semantics of these data buffers are the following.

+
    +
  1. Both key data and match action data (parameters) are passed in in-order.
  2. +
  3. Numeric types are serialized in big-endian byte order.
  4. +
  5. If a set of keys or a set of parameters results in a size that does not land +on a byte-boundary, i.e. 12 bytes like we have in this example, the length of +the buffer is rounded up to the nearest byte boundary.
  6. +
+

After adding the forwarding entries, VLAN table entries are added in the same +manner. A VLAN with the vid of 47 is added to the first and second ports. +Note that we also use a table access method to get all the entries of a table +and print them out to convince ourselves our code is doing what we intend.

+

Test Code

+

Now let's take a look at the test portion of our code.

+
fn run_test(
+    pipeline: main_pipeline,
+    m2: [u8; 6],
+    m3: [u8; 6],
+) -> Result<(), anyhow::Error> {
+    // create and run the softnpu instance
+    let mut npu = SoftNpu::new(2, pipeline, false);
+    let phy1 = npu.phy(0);
+    let phy2 = npu.phy(1);
+    npu.run();
+
+    // send a packet we expect to make it through
+    phy1.send(&[TxFrame::newv(m2, 0, b"blueberry", 47)])?;
+    expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b"blueberry", 47)]);
+
+    // send 3 packets, we expect the first 2 to get filtered by vlan rules
+    phy1.send(&[TxFrame::newv(m2, 0, b"poppyseed", 74)])?; // 74 != 47
+    phy1.send(&[TxFrame::new(m2, 0, b"banana")])?; // no tag
+    phy1.send(&[TxFrame::newv(m2, 0, b"muffin", 47)])?;
+    phy1.send(&[TxFrame::newv(m3, 0, b"nut", 47)])?; // no forwarding entry
+    expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b"muffin", 47)]);
+
+    Ok(())
+}
+

The first thing we do here is create a SoftNpu virtual ASIC instance with 2 +ports that will execute the pipeline we configured with entries in the previous +section. We get references to each ASIC port and run the ASIC.

+

Next we send a few packets through the ASIC to validate that our P4 program is +doing what we expect given how we have configured the tables.

+

The first test passes through a packet we expect to make it through the VLAN +filtering. The next test sends 4 packets in the ASIC, but we expect our P4 +program to filter 3 of them out.

+
    +
  • The first packet has the wrong vid.
  • +
  • The second packet has no vid.
  • +
  • The third packet should make it through.
  • +
  • The fourth packet has no forwarding entry.
  • +
+

Running the test

+

When we run this program we see the following

+
$ cargo run --bin vlan-switch
+    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
+     Running `target/debug/vlan-switch`
+[
+    TableEntry {
+        action_id: "filter",
+        keyset_data: [
+            0,
+            0,
+        ],
+        parameter_data: [
+            0,
+            47,
+        ],
+    },
+]
+[phy2] blueberry
+drop
+drop
+drop
+[phy2] muffin
+
+

The first thing we see is our little sanity check dumping out the VLAN table +after adding a single entry. This has what we expect, mapping the port 0 to +the vid 47.

+

Next we start sending packets through the ASIC. There are two frame constructors +in play here. TxFrame::newv creates an Ethernet frame with a VLAN header and +TxFrame::new creates just a plane old Ethernet frame. The first argument to +each frame constructor is the destination MAC address. The second argument is +the ethertype to use and the third argument is the Ethernet payload.

+

Next we see that our blueberry packet made it through as expected. Then we see +three packets getting dropped as we expect. And finally we see the muffin packet +coming through as expected.

+

You can find this program in it's entirety +here.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/02-by-example.html b/book/02-by-example.html new file mode 100644 index 00000000..d12e179d --- /dev/null +++ b/book/02-by-example.html @@ -0,0 +1,223 @@ + + + + + + By Example - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

By Example

+

This chapter presents the use of the P4 language and x4c through a series of +examples. This is a living set that will grow over time.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/03-01-endianness.html b/book/03-01-endianness.html new file mode 100644 index 00000000..6c9e8db1 --- /dev/null +++ b/book/03-01-endianness.html @@ -0,0 +1,228 @@ + + + + + + Endianness - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Endianness

+

The basic rules for endianness follow. Generally speaking numeric fields are in +big endian when they come in off the wire, little endian while in the program, +and transformed back to big endian on the way back out onto the wire. We refer +to this as confused endian.

+
    +
  1. All numeric packet field data is big endian when enters and leaves a p4 +program.
  2. +
  3. All numeric data, including packet fields is little endian inside a p4 +program.
  4. +
  5. Table keys with the exact and range type defined over bit types are in +little endian.
  6. +
  7. Table keys with the lpm type are in the byte order they appear on the wire.
  8. +
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/03-guidelines.html b/book/03-guidelines.html new file mode 100644 index 00000000..756ca653 --- /dev/null +++ b/book/03-guidelines.html @@ -0,0 +1,222 @@ + + + + + + Guidelines - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Guidelines

+

Ths chapter provides guidelines on various aspects of the x4c compiler.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/404.html b/book/404.html new file mode 100644 index 00000000..7b372ff5 --- /dev/null +++ b/book/404.html @@ -0,0 +1,211 @@ + + + + + + Page not found - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

Document not found (404)

+

This URL is invalid, sorry. Please use the navigation bar or search to continue.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/FontAwesome/css/font-awesome.css b/book/FontAwesome/css/font-awesome.css new file mode 100644 index 00000000..540440ce --- /dev/null +++ b/book/FontAwesome/css/font-awesome.css @@ -0,0 +1,4 @@ +/*! + * Font Awesome 4.7.0 by @davegandy - http://fontawesome.io - @fontawesome + * License - http://fontawesome.io/license (Font: SIL OFL 1.1, CSS: MIT License) + */@font-face{font-family:'FontAwesome';src:url('../fonts/fontawesome-webfont.eot?v=4.7.0');src:url('../fonts/fontawesome-webfont.eot?#iefix&v=4.7.0') format('embedded-opentype'),url('../fonts/fontawesome-webfont.woff2?v=4.7.0') format('woff2'),url('../fonts/fontawesome-webfont.woff?v=4.7.0') format('woff'),url('../fonts/fontawesome-webfont.ttf?v=4.7.0') format('truetype'),url('../fonts/fontawesome-webfont.svg?v=4.7.0#fontawesomeregular') format('svg');font-weight:normal;font-style:normal}.fa{display:inline-block;font:normal normal normal 14px/1 FontAwesome;font-size:inherit;text-rendering:auto;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.fa-lg{font-size:1.33333333em;line-height:.75em;vertical-align:-15%}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-fw{width:1.28571429em;text-align:center}.fa-ul{padding-left:0;margin-left:2.14285714em;list-style-type:none}.fa-ul>li{position:relative}.fa-li{position:absolute;left:-2.14285714em;width:2.14285714em;top:.14285714em;text-align:center}.fa-li.fa-lg{left:-1.85714286em}.fa-border{padding:.2em .25em .15em;border:solid .08em #eee;border-radius:.1em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left{margin-right:.3em}.fa.fa-pull-right{margin-left:.3em}.pull-right{float:right}.pull-left{float:left}.fa.pull-left{margin-right:.3em}.fa.pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s infinite linear;animation:fa-spin 2s infinite linear}.fa-pulse{-webkit-animation:fa-spin 1s infinite steps(8);animation:fa-spin 1s infinite steps(8)}@-webkit-keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}@keyframes fa-spin{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(359deg);transform:rotate(359deg)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";-webkit-transform:rotate(90deg);-ms-transform:rotate(90deg);transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";-webkit-transform:rotate(180deg);-ms-transform:rotate(180deg);transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";-webkit-transform:rotate(270deg);-ms-transform:rotate(270deg);transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";-webkit-transform:scale(-1, 1);-ms-transform:scale(-1, 1);transform:scale(-1, 1)}.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)";-webkit-transform:scale(1, -1);-ms-transform:scale(1, -1);transform:scale(1, -1)}:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270,:root .fa-flip-horizontal,:root .fa-flip-vertical{filter:none}.fa-stack{position:relative;display:inline-block;width:2em;height:2em;line-height:2em;vertical-align:middle}.fa-stack-1x,.fa-stack-2x{position:absolute;left:0;width:100%;text-align:center}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-glass:before{content:"\f000"}.fa-music:before{content:"\f001"}.fa-search:before{content:"\f002"}.fa-envelope-o:before{content:"\f003"}.fa-heart:before{content:"\f004"}.fa-star:before{content:"\f005"}.fa-star-o:before{content:"\f006"}.fa-user:before{content:"\f007"}.fa-film:before{content:"\f008"}.fa-th-large:before{content:"\f009"}.fa-th:before{content:"\f00a"}.fa-th-list:before{content:"\f00b"}.fa-check:before{content:"\f00c"}.fa-remove:before,.fa-close:before,.fa-times:before{content:"\f00d"}.fa-search-plus:before{content:"\f00e"}.fa-search-minus:before{content:"\f010"}.fa-power-off:before{content:"\f011"}.fa-signal:before{content:"\f012"}.fa-gear:before,.fa-cog:before{content:"\f013"}.fa-trash-o:before{content:"\f014"}.fa-home:before{content:"\f015"}.fa-file-o:before{content:"\f016"}.fa-clock-o:before{content:"\f017"}.fa-road:before{content:"\f018"}.fa-download:before{content:"\f019"}.fa-arrow-circle-o-down:before{content:"\f01a"}.fa-arrow-circle-o-up:before{content:"\f01b"}.fa-inbox:before{content:"\f01c"}.fa-play-circle-o:before{content:"\f01d"}.fa-rotate-right:before,.fa-repeat:before{content:"\f01e"}.fa-refresh:before{content:"\f021"}.fa-list-alt:before{content:"\f022"}.fa-lock:before{content:"\f023"}.fa-flag:before{content:"\f024"}.fa-headphones:before{content:"\f025"}.fa-volume-off:before{content:"\f026"}.fa-volume-down:before{content:"\f027"}.fa-volume-up:before{content:"\f028"}.fa-qrcode:before{content:"\f029"}.fa-barcode:before{content:"\f02a"}.fa-tag:before{content:"\f02b"}.fa-tags:before{content:"\f02c"}.fa-book:before{content:"\f02d"}.fa-bookmark:before{content:"\f02e"}.fa-print:before{content:"\f02f"}.fa-camera:before{content:"\f030"}.fa-font:before{content:"\f031"}.fa-bold:before{content:"\f032"}.fa-italic:before{content:"\f033"}.fa-text-height:before{content:"\f034"}.fa-text-width:before{content:"\f035"}.fa-align-left:before{content:"\f036"}.fa-align-center:before{content:"\f037"}.fa-align-right:before{content:"\f038"}.fa-align-justify:before{content:"\f039"}.fa-list:before{content:"\f03a"}.fa-dedent:before,.fa-outdent:before{content:"\f03b"}.fa-indent:before{content:"\f03c"}.fa-video-camera:before{content:"\f03d"}.fa-photo:before,.fa-image:before,.fa-picture-o:before{content:"\f03e"}.fa-pencil:before{content:"\f040"}.fa-map-marker:before{content:"\f041"}.fa-adjust:before{content:"\f042"}.fa-tint:before{content:"\f043"}.fa-edit:before,.fa-pencil-square-o:before{content:"\f044"}.fa-share-square-o:before{content:"\f045"}.fa-check-square-o:before{content:"\f046"}.fa-arrows:before{content:"\f047"}.fa-step-backward:before{content:"\f048"}.fa-fast-backward:before{content:"\f049"}.fa-backward:before{content:"\f04a"}.fa-play:before{content:"\f04b"}.fa-pause:before{content:"\f04c"}.fa-stop:before{content:"\f04d"}.fa-forward:before{content:"\f04e"}.fa-fast-forward:before{content:"\f050"}.fa-step-forward:before{content:"\f051"}.fa-eject:before{content:"\f052"}.fa-chevron-left:before{content:"\f053"}.fa-chevron-right:before{content:"\f054"}.fa-plus-circle:before{content:"\f055"}.fa-minus-circle:before{content:"\f056"}.fa-times-circle:before{content:"\f057"}.fa-check-circle:before{content:"\f058"}.fa-question-circle:before{content:"\f059"}.fa-info-circle:before{content:"\f05a"}.fa-crosshairs:before{content:"\f05b"}.fa-times-circle-o:before{content:"\f05c"}.fa-check-circle-o:before{content:"\f05d"}.fa-ban:before{content:"\f05e"}.fa-arrow-left:before{content:"\f060"}.fa-arrow-right:before{content:"\f061"}.fa-arrow-up:before{content:"\f062"}.fa-arrow-down:before{content:"\f063"}.fa-mail-forward:before,.fa-share:before{content:"\f064"}.fa-expand:before{content:"\f065"}.fa-compress:before{content:"\f066"}.fa-plus:before{content:"\f067"}.fa-minus:before{content:"\f068"}.fa-asterisk:before{content:"\f069"}.fa-exclamation-circle:before{content:"\f06a"}.fa-gift:before{content:"\f06b"}.fa-leaf:before{content:"\f06c"}.fa-fire:before{content:"\f06d"}.fa-eye:before{content:"\f06e"}.fa-eye-slash:before{content:"\f070"}.fa-warning:before,.fa-exclamation-triangle:before{content:"\f071"}.fa-plane:before{content:"\f072"}.fa-calendar:before{content:"\f073"}.fa-random:before{content:"\f074"}.fa-comment:before{content:"\f075"}.fa-magnet:before{content:"\f076"}.fa-chevron-up:before{content:"\f077"}.fa-chevron-down:before{content:"\f078"}.fa-retweet:before{content:"\f079"}.fa-shopping-cart:before{content:"\f07a"}.fa-folder:before{content:"\f07b"}.fa-folder-open:before{content:"\f07c"}.fa-arrows-v:before{content:"\f07d"}.fa-arrows-h:before{content:"\f07e"}.fa-bar-chart-o:before,.fa-bar-chart:before{content:"\f080"}.fa-twitter-square:before{content:"\f081"}.fa-facebook-square:before{content:"\f082"}.fa-camera-retro:before{content:"\f083"}.fa-key:before{content:"\f084"}.fa-gears:before,.fa-cogs:before{content:"\f085"}.fa-comments:before{content:"\f086"}.fa-thumbs-o-up:before{content:"\f087"}.fa-thumbs-o-down:before{content:"\f088"}.fa-star-half:before{content:"\f089"}.fa-heart-o:before{content:"\f08a"}.fa-sign-out:before{content:"\f08b"}.fa-linkedin-square:before{content:"\f08c"}.fa-thumb-tack:before{content:"\f08d"}.fa-external-link:before{content:"\f08e"}.fa-sign-in:before{content:"\f090"}.fa-trophy:before{content:"\f091"}.fa-github-square:before{content:"\f092"}.fa-upload:before{content:"\f093"}.fa-lemon-o:before{content:"\f094"}.fa-phone:before{content:"\f095"}.fa-square-o:before{content:"\f096"}.fa-bookmark-o:before{content:"\f097"}.fa-phone-square:before{content:"\f098"}.fa-twitter:before{content:"\f099"}.fa-facebook-f:before,.fa-facebook:before{content:"\f09a"}.fa-github:before{content:"\f09b"}.fa-unlock:before{content:"\f09c"}.fa-credit-card:before{content:"\f09d"}.fa-feed:before,.fa-rss:before{content:"\f09e"}.fa-hdd-o:before{content:"\f0a0"}.fa-bullhorn:before{content:"\f0a1"}.fa-bell:before{content:"\f0f3"}.fa-certificate:before{content:"\f0a3"}.fa-hand-o-right:before{content:"\f0a4"}.fa-hand-o-left:before{content:"\f0a5"}.fa-hand-o-up:before{content:"\f0a6"}.fa-hand-o-down:before{content:"\f0a7"}.fa-arrow-circle-left:before{content:"\f0a8"}.fa-arrow-circle-right:before{content:"\f0a9"}.fa-arrow-circle-up:before{content:"\f0aa"}.fa-arrow-circle-down:before{content:"\f0ab"}.fa-globe:before{content:"\f0ac"}.fa-wrench:before{content:"\f0ad"}.fa-tasks:before{content:"\f0ae"}.fa-filter:before{content:"\f0b0"}.fa-briefcase:before{content:"\f0b1"}.fa-arrows-alt:before{content:"\f0b2"}.fa-group:before,.fa-users:before{content:"\f0c0"}.fa-chain:before,.fa-link:before{content:"\f0c1"}.fa-cloud:before{content:"\f0c2"}.fa-flask:before{content:"\f0c3"}.fa-cut:before,.fa-scissors:before{content:"\f0c4"}.fa-copy:before,.fa-files-o:before{content:"\f0c5"}.fa-paperclip:before{content:"\f0c6"}.fa-save:before,.fa-floppy-o:before{content:"\f0c7"}.fa-square:before{content:"\f0c8"}.fa-navicon:before,.fa-reorder:before,.fa-bars:before{content:"\f0c9"}.fa-list-ul:before{content:"\f0ca"}.fa-list-ol:before{content:"\f0cb"}.fa-strikethrough:before{content:"\f0cc"}.fa-underline:before{content:"\f0cd"}.fa-table:before{content:"\f0ce"}.fa-magic:before{content:"\f0d0"}.fa-truck:before{content:"\f0d1"}.fa-pinterest:before{content:"\f0d2"}.fa-pinterest-square:before{content:"\f0d3"}.fa-google-plus-square:before{content:"\f0d4"}.fa-google-plus:before{content:"\f0d5"}.fa-money:before{content:"\f0d6"}.fa-caret-down:before{content:"\f0d7"}.fa-caret-up:before{content:"\f0d8"}.fa-caret-left:before{content:"\f0d9"}.fa-caret-right:before{content:"\f0da"}.fa-columns:before{content:"\f0db"}.fa-unsorted:before,.fa-sort:before{content:"\f0dc"}.fa-sort-down:before,.fa-sort-desc:before{content:"\f0dd"}.fa-sort-up:before,.fa-sort-asc:before{content:"\f0de"}.fa-envelope:before{content:"\f0e0"}.fa-linkedin:before{content:"\f0e1"}.fa-rotate-left:before,.fa-undo:before{content:"\f0e2"}.fa-legal:before,.fa-gavel:before{content:"\f0e3"}.fa-dashboard:before,.fa-tachometer:before{content:"\f0e4"}.fa-comment-o:before{content:"\f0e5"}.fa-comments-o:before{content:"\f0e6"}.fa-flash:before,.fa-bolt:before{content:"\f0e7"}.fa-sitemap:before{content:"\f0e8"}.fa-umbrella:before{content:"\f0e9"}.fa-paste:before,.fa-clipboard:before{content:"\f0ea"}.fa-lightbulb-o:before{content:"\f0eb"}.fa-exchange:before{content:"\f0ec"}.fa-cloud-download:before{content:"\f0ed"}.fa-cloud-upload:before{content:"\f0ee"}.fa-user-md:before{content:"\f0f0"}.fa-stethoscope:before{content:"\f0f1"}.fa-suitcase:before{content:"\f0f2"}.fa-bell-o:before{content:"\f0a2"}.fa-coffee:before{content:"\f0f4"}.fa-cutlery:before{content:"\f0f5"}.fa-file-text-o:before{content:"\f0f6"}.fa-building-o:before{content:"\f0f7"}.fa-hospital-o:before{content:"\f0f8"}.fa-ambulance:before{content:"\f0f9"}.fa-medkit:before{content:"\f0fa"}.fa-fighter-jet:before{content:"\f0fb"}.fa-beer:before{content:"\f0fc"}.fa-h-square:before{content:"\f0fd"}.fa-plus-square:before{content:"\f0fe"}.fa-angle-double-left:before{content:"\f100"}.fa-angle-double-right:before{content:"\f101"}.fa-angle-double-up:before{content:"\f102"}.fa-angle-double-down:before{content:"\f103"}.fa-angle-left:before{content:"\f104"}.fa-angle-right:before{content:"\f105"}.fa-angle-up:before{content:"\f106"}.fa-angle-down:before{content:"\f107"}.fa-desktop:before{content:"\f108"}.fa-laptop:before{content:"\f109"}.fa-tablet:before{content:"\f10a"}.fa-mobile-phone:before,.fa-mobile:before{content:"\f10b"}.fa-circle-o:before{content:"\f10c"}.fa-quote-left:before{content:"\f10d"}.fa-quote-right:before{content:"\f10e"}.fa-spinner:before{content:"\f110"}.fa-circle:before{content:"\f111"}.fa-mail-reply:before,.fa-reply:before{content:"\f112"}.fa-github-alt:before{content:"\f113"}.fa-folder-o:before{content:"\f114"}.fa-folder-open-o:before{content:"\f115"}.fa-smile-o:before{content:"\f118"}.fa-frown-o:before{content:"\f119"}.fa-meh-o:before{content:"\f11a"}.fa-gamepad:before{content:"\f11b"}.fa-keyboard-o:before{content:"\f11c"}.fa-flag-o:before{content:"\f11d"}.fa-flag-checkered:before{content:"\f11e"}.fa-terminal:before{content:"\f120"}.fa-code:before{content:"\f121"}.fa-mail-reply-all:before,.fa-reply-all:before{content:"\f122"}.fa-star-half-empty:before,.fa-star-half-full:before,.fa-star-half-o:before{content:"\f123"}.fa-location-arrow:before{content:"\f124"}.fa-crop:before{content:"\f125"}.fa-code-fork:before{content:"\f126"}.fa-unlink:before,.fa-chain-broken:before{content:"\f127"}.fa-question:before{content:"\f128"}.fa-info:before{content:"\f129"}.fa-exclamation:before{content:"\f12a"}.fa-superscript:before{content:"\f12b"}.fa-subscript:before{content:"\f12c"}.fa-eraser:before{content:"\f12d"}.fa-puzzle-piece:before{content:"\f12e"}.fa-microphone:before{content:"\f130"}.fa-microphone-slash:before{content:"\f131"}.fa-shield:before{content:"\f132"}.fa-calendar-o:before{content:"\f133"}.fa-fire-extinguisher:before{content:"\f134"}.fa-rocket:before{content:"\f135"}.fa-maxcdn:before{content:"\f136"}.fa-chevron-circle-left:before{content:"\f137"}.fa-chevron-circle-right:before{content:"\f138"}.fa-chevron-circle-up:before{content:"\f139"}.fa-chevron-circle-down:before{content:"\f13a"}.fa-html5:before{content:"\f13b"}.fa-css3:before{content:"\f13c"}.fa-anchor:before{content:"\f13d"}.fa-unlock-alt:before{content:"\f13e"}.fa-bullseye:before{content:"\f140"}.fa-ellipsis-h:before{content:"\f141"}.fa-ellipsis-v:before{content:"\f142"}.fa-rss-square:before{content:"\f143"}.fa-play-circle:before{content:"\f144"}.fa-ticket:before{content:"\f145"}.fa-minus-square:before{content:"\f146"}.fa-minus-square-o:before{content:"\f147"}.fa-level-up:before{content:"\f148"}.fa-level-down:before{content:"\f149"}.fa-check-square:before{content:"\f14a"}.fa-pencil-square:before{content:"\f14b"}.fa-external-link-square:before{content:"\f14c"}.fa-share-square:before{content:"\f14d"}.fa-compass:before{content:"\f14e"}.fa-toggle-down:before,.fa-caret-square-o-down:before{content:"\f150"}.fa-toggle-up:before,.fa-caret-square-o-up:before{content:"\f151"}.fa-toggle-right:before,.fa-caret-square-o-right:before{content:"\f152"}.fa-euro:before,.fa-eur:before{content:"\f153"}.fa-gbp:before{content:"\f154"}.fa-dollar:before,.fa-usd:before{content:"\f155"}.fa-rupee:before,.fa-inr:before{content:"\f156"}.fa-cny:before,.fa-rmb:before,.fa-yen:before,.fa-jpy:before{content:"\f157"}.fa-ruble:before,.fa-rouble:before,.fa-rub:before{content:"\f158"}.fa-won:before,.fa-krw:before{content:"\f159"}.fa-bitcoin:before,.fa-btc:before{content:"\f15a"}.fa-file:before{content:"\f15b"}.fa-file-text:before{content:"\f15c"}.fa-sort-alpha-asc:before{content:"\f15d"}.fa-sort-alpha-desc:before{content:"\f15e"}.fa-sort-amount-asc:before{content:"\f160"}.fa-sort-amount-desc:before{content:"\f161"}.fa-sort-numeric-asc:before{content:"\f162"}.fa-sort-numeric-desc:before{content:"\f163"}.fa-thumbs-up:before{content:"\f164"}.fa-thumbs-down:before{content:"\f165"}.fa-youtube-square:before{content:"\f166"}.fa-youtube:before{content:"\f167"}.fa-xing:before{content:"\f168"}.fa-xing-square:before{content:"\f169"}.fa-youtube-play:before{content:"\f16a"}.fa-dropbox:before{content:"\f16b"}.fa-stack-overflow:before{content:"\f16c"}.fa-instagram:before{content:"\f16d"}.fa-flickr:before{content:"\f16e"}.fa-adn:before{content:"\f170"}.fa-bitbucket:before{content:"\f171"}.fa-bitbucket-square:before{content:"\f172"}.fa-tumblr:before{content:"\f173"}.fa-tumblr-square:before{content:"\f174"}.fa-long-arrow-down:before{content:"\f175"}.fa-long-arrow-up:before{content:"\f176"}.fa-long-arrow-left:before{content:"\f177"}.fa-long-arrow-right:before{content:"\f178"}.fa-apple:before{content:"\f179"}.fa-windows:before{content:"\f17a"}.fa-android:before{content:"\f17b"}.fa-linux:before{content:"\f17c"}.fa-dribbble:before{content:"\f17d"}.fa-skype:before{content:"\f17e"}.fa-foursquare:before{content:"\f180"}.fa-trello:before{content:"\f181"}.fa-female:before{content:"\f182"}.fa-male:before{content:"\f183"}.fa-gittip:before,.fa-gratipay:before{content:"\f184"}.fa-sun-o:before{content:"\f185"}.fa-moon-o:before{content:"\f186"}.fa-archive:before{content:"\f187"}.fa-bug:before{content:"\f188"}.fa-vk:before{content:"\f189"}.fa-weibo:before{content:"\f18a"}.fa-renren:before{content:"\f18b"}.fa-pagelines:before{content:"\f18c"}.fa-stack-exchange:before{content:"\f18d"}.fa-arrow-circle-o-right:before{content:"\f18e"}.fa-arrow-circle-o-left:before{content:"\f190"}.fa-toggle-left:before,.fa-caret-square-o-left:before{content:"\f191"}.fa-dot-circle-o:before{content:"\f192"}.fa-wheelchair:before{content:"\f193"}.fa-vimeo-square:before{content:"\f194"}.fa-turkish-lira:before,.fa-try:before{content:"\f195"}.fa-plus-square-o:before{content:"\f196"}.fa-space-shuttle:before{content:"\f197"}.fa-slack:before{content:"\f198"}.fa-envelope-square:before{content:"\f199"}.fa-wordpress:before{content:"\f19a"}.fa-openid:before{content:"\f19b"}.fa-institution:before,.fa-bank:before,.fa-university:before{content:"\f19c"}.fa-mortar-board:before,.fa-graduation-cap:before{content:"\f19d"}.fa-yahoo:before{content:"\f19e"}.fa-google:before{content:"\f1a0"}.fa-reddit:before{content:"\f1a1"}.fa-reddit-square:before{content:"\f1a2"}.fa-stumbleupon-circle:before{content:"\f1a3"}.fa-stumbleupon:before{content:"\f1a4"}.fa-delicious:before{content:"\f1a5"}.fa-digg:before{content:"\f1a6"}.fa-pied-piper-pp:before{content:"\f1a7"}.fa-pied-piper-alt:before{content:"\f1a8"}.fa-drupal:before{content:"\f1a9"}.fa-joomla:before{content:"\f1aa"}.fa-language:before{content:"\f1ab"}.fa-fax:before{content:"\f1ac"}.fa-building:before{content:"\f1ad"}.fa-child:before{content:"\f1ae"}.fa-paw:before{content:"\f1b0"}.fa-spoon:before{content:"\f1b1"}.fa-cube:before{content:"\f1b2"}.fa-cubes:before{content:"\f1b3"}.fa-behance:before{content:"\f1b4"}.fa-behance-square:before{content:"\f1b5"}.fa-steam:before{content:"\f1b6"}.fa-steam-square:before{content:"\f1b7"}.fa-recycle:before{content:"\f1b8"}.fa-automobile:before,.fa-car:before{content:"\f1b9"}.fa-cab:before,.fa-taxi:before{content:"\f1ba"}.fa-tree:before{content:"\f1bb"}.fa-spotify:before{content:"\f1bc"}.fa-deviantart:before{content:"\f1bd"}.fa-soundcloud:before{content:"\f1be"}.fa-database:before{content:"\f1c0"}.fa-file-pdf-o:before{content:"\f1c1"}.fa-file-word-o:before{content:"\f1c2"}.fa-file-excel-o:before{content:"\f1c3"}.fa-file-powerpoint-o:before{content:"\f1c4"}.fa-file-photo-o:before,.fa-file-picture-o:before,.fa-file-image-o:before{content:"\f1c5"}.fa-file-zip-o:before,.fa-file-archive-o:before{content:"\f1c6"}.fa-file-sound-o:before,.fa-file-audio-o:before{content:"\f1c7"}.fa-file-movie-o:before,.fa-file-video-o:before{content:"\f1c8"}.fa-file-code-o:before{content:"\f1c9"}.fa-vine:before{content:"\f1ca"}.fa-codepen:before{content:"\f1cb"}.fa-jsfiddle:before{content:"\f1cc"}.fa-life-bouy:before,.fa-life-buoy:before,.fa-life-saver:before,.fa-support:before,.fa-life-ring:before{content:"\f1cd"}.fa-circle-o-notch:before{content:"\f1ce"}.fa-ra:before,.fa-resistance:before,.fa-rebel:before{content:"\f1d0"}.fa-ge:before,.fa-empire:before{content:"\f1d1"}.fa-git-square:before{content:"\f1d2"}.fa-git:before{content:"\f1d3"}.fa-y-combinator-square:before,.fa-yc-square:before,.fa-hacker-news:before{content:"\f1d4"}.fa-tencent-weibo:before{content:"\f1d5"}.fa-qq:before{content:"\f1d6"}.fa-wechat:before,.fa-weixin:before{content:"\f1d7"}.fa-send:before,.fa-paper-plane:before{content:"\f1d8"}.fa-send-o:before,.fa-paper-plane-o:before{content:"\f1d9"}.fa-history:before{content:"\f1da"}.fa-circle-thin:before{content:"\f1db"}.fa-header:before{content:"\f1dc"}.fa-paragraph:before{content:"\f1dd"}.fa-sliders:before{content:"\f1de"}.fa-share-alt:before{content:"\f1e0"}.fa-share-alt-square:before{content:"\f1e1"}.fa-bomb:before{content:"\f1e2"}.fa-soccer-ball-o:before,.fa-futbol-o:before{content:"\f1e3"}.fa-tty:before{content:"\f1e4"}.fa-binoculars:before{content:"\f1e5"}.fa-plug:before{content:"\f1e6"}.fa-slideshare:before{content:"\f1e7"}.fa-twitch:before{content:"\f1e8"}.fa-yelp:before{content:"\f1e9"}.fa-newspaper-o:before{content:"\f1ea"}.fa-wifi:before{content:"\f1eb"}.fa-calculator:before{content:"\f1ec"}.fa-paypal:before{content:"\f1ed"}.fa-google-wallet:before{content:"\f1ee"}.fa-cc-visa:before{content:"\f1f0"}.fa-cc-mastercard:before{content:"\f1f1"}.fa-cc-discover:before{content:"\f1f2"}.fa-cc-amex:before{content:"\f1f3"}.fa-cc-paypal:before{content:"\f1f4"}.fa-cc-stripe:before{content:"\f1f5"}.fa-bell-slash:before{content:"\f1f6"}.fa-bell-slash-o:before{content:"\f1f7"}.fa-trash:before{content:"\f1f8"}.fa-copyright:before{content:"\f1f9"}.fa-at:before{content:"\f1fa"}.fa-eyedropper:before{content:"\f1fb"}.fa-paint-brush:before{content:"\f1fc"}.fa-birthday-cake:before{content:"\f1fd"}.fa-area-chart:before{content:"\f1fe"}.fa-pie-chart:before{content:"\f200"}.fa-line-chart:before{content:"\f201"}.fa-lastfm:before{content:"\f202"}.fa-lastfm-square:before{content:"\f203"}.fa-toggle-off:before{content:"\f204"}.fa-toggle-on:before{content:"\f205"}.fa-bicycle:before{content:"\f206"}.fa-bus:before{content:"\f207"}.fa-ioxhost:before{content:"\f208"}.fa-angellist:before{content:"\f209"}.fa-cc:before{content:"\f20a"}.fa-shekel:before,.fa-sheqel:before,.fa-ils:before{content:"\f20b"}.fa-meanpath:before{content:"\f20c"}.fa-buysellads:before{content:"\f20d"}.fa-connectdevelop:before{content:"\f20e"}.fa-dashcube:before{content:"\f210"}.fa-forumbee:before{content:"\f211"}.fa-leanpub:before{content:"\f212"}.fa-sellsy:before{content:"\f213"}.fa-shirtsinbulk:before{content:"\f214"}.fa-simplybuilt:before{content:"\f215"}.fa-skyatlas:before{content:"\f216"}.fa-cart-plus:before{content:"\f217"}.fa-cart-arrow-down:before{content:"\f218"}.fa-diamond:before{content:"\f219"}.fa-ship:before{content:"\f21a"}.fa-user-secret:before{content:"\f21b"}.fa-motorcycle:before{content:"\f21c"}.fa-street-view:before{content:"\f21d"}.fa-heartbeat:before{content:"\f21e"}.fa-venus:before{content:"\f221"}.fa-mars:before{content:"\f222"}.fa-mercury:before{content:"\f223"}.fa-intersex:before,.fa-transgender:before{content:"\f224"}.fa-transgender-alt:before{content:"\f225"}.fa-venus-double:before{content:"\f226"}.fa-mars-double:before{content:"\f227"}.fa-venus-mars:before{content:"\f228"}.fa-mars-stroke:before{content:"\f229"}.fa-mars-stroke-v:before{content:"\f22a"}.fa-mars-stroke-h:before{content:"\f22b"}.fa-neuter:before{content:"\f22c"}.fa-genderless:before{content:"\f22d"}.fa-facebook-official:before{content:"\f230"}.fa-pinterest-p:before{content:"\f231"}.fa-whatsapp:before{content:"\f232"}.fa-server:before{content:"\f233"}.fa-user-plus:before{content:"\f234"}.fa-user-times:before{content:"\f235"}.fa-hotel:before,.fa-bed:before{content:"\f236"}.fa-viacoin:before{content:"\f237"}.fa-train:before{content:"\f238"}.fa-subway:before{content:"\f239"}.fa-medium:before{content:"\f23a"}.fa-yc:before,.fa-y-combinator:before{content:"\f23b"}.fa-optin-monster:before{content:"\f23c"}.fa-opencart:before{content:"\f23d"}.fa-expeditedssl:before{content:"\f23e"}.fa-battery-4:before,.fa-battery:before,.fa-battery-full:before{content:"\f240"}.fa-battery-3:before,.fa-battery-three-quarters:before{content:"\f241"}.fa-battery-2:before,.fa-battery-half:before{content:"\f242"}.fa-battery-1:before,.fa-battery-quarter:before{content:"\f243"}.fa-battery-0:before,.fa-battery-empty:before{content:"\f244"}.fa-mouse-pointer:before{content:"\f245"}.fa-i-cursor:before{content:"\f246"}.fa-object-group:before{content:"\f247"}.fa-object-ungroup:before{content:"\f248"}.fa-sticky-note:before{content:"\f249"}.fa-sticky-note-o:before{content:"\f24a"}.fa-cc-jcb:before{content:"\f24b"}.fa-cc-diners-club:before{content:"\f24c"}.fa-clone:before{content:"\f24d"}.fa-balance-scale:before{content:"\f24e"}.fa-hourglass-o:before{content:"\f250"}.fa-hourglass-1:before,.fa-hourglass-start:before{content:"\f251"}.fa-hourglass-2:before,.fa-hourglass-half:before{content:"\f252"}.fa-hourglass-3:before,.fa-hourglass-end:before{content:"\f253"}.fa-hourglass:before{content:"\f254"}.fa-hand-grab-o:before,.fa-hand-rock-o:before{content:"\f255"}.fa-hand-stop-o:before,.fa-hand-paper-o:before{content:"\f256"}.fa-hand-scissors-o:before{content:"\f257"}.fa-hand-lizard-o:before{content:"\f258"}.fa-hand-spock-o:before{content:"\f259"}.fa-hand-pointer-o:before{content:"\f25a"}.fa-hand-peace-o:before{content:"\f25b"}.fa-trademark:before{content:"\f25c"}.fa-registered:before{content:"\f25d"}.fa-creative-commons:before{content:"\f25e"}.fa-gg:before{content:"\f260"}.fa-gg-circle:before{content:"\f261"}.fa-tripadvisor:before{content:"\f262"}.fa-odnoklassniki:before{content:"\f263"}.fa-odnoklassniki-square:before{content:"\f264"}.fa-get-pocket:before{content:"\f265"}.fa-wikipedia-w:before{content:"\f266"}.fa-safari:before{content:"\f267"}.fa-chrome:before{content:"\f268"}.fa-firefox:before{content:"\f269"}.fa-opera:before{content:"\f26a"}.fa-internet-explorer:before{content:"\f26b"}.fa-tv:before,.fa-television:before{content:"\f26c"}.fa-contao:before{content:"\f26d"}.fa-500px:before{content:"\f26e"}.fa-amazon:before{content:"\f270"}.fa-calendar-plus-o:before{content:"\f271"}.fa-calendar-minus-o:before{content:"\f272"}.fa-calendar-times-o:before{content:"\f273"}.fa-calendar-check-o:before{content:"\f274"}.fa-industry:before{content:"\f275"}.fa-map-pin:before{content:"\f276"}.fa-map-signs:before{content:"\f277"}.fa-map-o:before{content:"\f278"}.fa-map:before{content:"\f279"}.fa-commenting:before{content:"\f27a"}.fa-commenting-o:before{content:"\f27b"}.fa-houzz:before{content:"\f27c"}.fa-vimeo:before{content:"\f27d"}.fa-black-tie:before{content:"\f27e"}.fa-fonticons:before{content:"\f280"}.fa-reddit-alien:before{content:"\f281"}.fa-edge:before{content:"\f282"}.fa-credit-card-alt:before{content:"\f283"}.fa-codiepie:before{content:"\f284"}.fa-modx:before{content:"\f285"}.fa-fort-awesome:before{content:"\f286"}.fa-usb:before{content:"\f287"}.fa-product-hunt:before{content:"\f288"}.fa-mixcloud:before{content:"\f289"}.fa-scribd:before{content:"\f28a"}.fa-pause-circle:before{content:"\f28b"}.fa-pause-circle-o:before{content:"\f28c"}.fa-stop-circle:before{content:"\f28d"}.fa-stop-circle-o:before{content:"\f28e"}.fa-shopping-bag:before{content:"\f290"}.fa-shopping-basket:before{content:"\f291"}.fa-hashtag:before{content:"\f292"}.fa-bluetooth:before{content:"\f293"}.fa-bluetooth-b:before{content:"\f294"}.fa-percent:before{content:"\f295"}.fa-gitlab:before{content:"\f296"}.fa-wpbeginner:before{content:"\f297"}.fa-wpforms:before{content:"\f298"}.fa-envira:before{content:"\f299"}.fa-universal-access:before{content:"\f29a"}.fa-wheelchair-alt:before{content:"\f29b"}.fa-question-circle-o:before{content:"\f29c"}.fa-blind:before{content:"\f29d"}.fa-audio-description:before{content:"\f29e"}.fa-volume-control-phone:before{content:"\f2a0"}.fa-braille:before{content:"\f2a1"}.fa-assistive-listening-systems:before{content:"\f2a2"}.fa-asl-interpreting:before,.fa-american-sign-language-interpreting:before{content:"\f2a3"}.fa-deafness:before,.fa-hard-of-hearing:before,.fa-deaf:before{content:"\f2a4"}.fa-glide:before{content:"\f2a5"}.fa-glide-g:before{content:"\f2a6"}.fa-signing:before,.fa-sign-language:before{content:"\f2a7"}.fa-low-vision:before{content:"\f2a8"}.fa-viadeo:before{content:"\f2a9"}.fa-viadeo-square:before{content:"\f2aa"}.fa-snapchat:before{content:"\f2ab"}.fa-snapchat-ghost:before{content:"\f2ac"}.fa-snapchat-square:before{content:"\f2ad"}.fa-pied-piper:before{content:"\f2ae"}.fa-first-order:before{content:"\f2b0"}.fa-yoast:before{content:"\f2b1"}.fa-themeisle:before{content:"\f2b2"}.fa-google-plus-circle:before,.fa-google-plus-official:before{content:"\f2b3"}.fa-fa:before,.fa-font-awesome:before{content:"\f2b4"}.fa-handshake-o:before{content:"\f2b5"}.fa-envelope-open:before{content:"\f2b6"}.fa-envelope-open-o:before{content:"\f2b7"}.fa-linode:before{content:"\f2b8"}.fa-address-book:before{content:"\f2b9"}.fa-address-book-o:before{content:"\f2ba"}.fa-vcard:before,.fa-address-card:before{content:"\f2bb"}.fa-vcard-o:before,.fa-address-card-o:before{content:"\f2bc"}.fa-user-circle:before{content:"\f2bd"}.fa-user-circle-o:before{content:"\f2be"}.fa-user-o:before{content:"\f2c0"}.fa-id-badge:before{content:"\f2c1"}.fa-drivers-license:before,.fa-id-card:before{content:"\f2c2"}.fa-drivers-license-o:before,.fa-id-card-o:before{content:"\f2c3"}.fa-quora:before{content:"\f2c4"}.fa-free-code-camp:before{content:"\f2c5"}.fa-telegram:before{content:"\f2c6"}.fa-thermometer-4:before,.fa-thermometer:before,.fa-thermometer-full:before{content:"\f2c7"}.fa-thermometer-3:before,.fa-thermometer-three-quarters:before{content:"\f2c8"}.fa-thermometer-2:before,.fa-thermometer-half:before{content:"\f2c9"}.fa-thermometer-1:before,.fa-thermometer-quarter:before{content:"\f2ca"}.fa-thermometer-0:before,.fa-thermometer-empty:before{content:"\f2cb"}.fa-shower:before{content:"\f2cc"}.fa-bathtub:before,.fa-s15:before,.fa-bath:before{content:"\f2cd"}.fa-podcast:before{content:"\f2ce"}.fa-window-maximize:before{content:"\f2d0"}.fa-window-minimize:before{content:"\f2d1"}.fa-window-restore:before{content:"\f2d2"}.fa-times-rectangle:before,.fa-window-close:before{content:"\f2d3"}.fa-times-rectangle-o:before,.fa-window-close-o:before{content:"\f2d4"}.fa-bandcamp:before{content:"\f2d5"}.fa-grav:before{content:"\f2d6"}.fa-etsy:before{content:"\f2d7"}.fa-imdb:before{content:"\f2d8"}.fa-ravelry:before{content:"\f2d9"}.fa-eercast:before{content:"\f2da"}.fa-microchip:before{content:"\f2db"}.fa-snowflake-o:before{content:"\f2dc"}.fa-superpowers:before{content:"\f2dd"}.fa-wpexplorer:before{content:"\f2de"}.fa-meetup:before{content:"\f2e0"}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto} diff --git a/book/FontAwesome/fonts/FontAwesome.ttf b/book/FontAwesome/fonts/FontAwesome.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/book/FontAwesome/fonts/FontAwesome.ttf differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.eot b/book/FontAwesome/fonts/fontawesome-webfont.eot new file mode 100644 index 00000000..e9f60ca9 Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.eot differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.svg b/book/FontAwesome/fonts/fontawesome-webfont.svg new file mode 100644 index 00000000..855c845e --- /dev/null +++ b/book/FontAwesome/fonts/fontawesome-webfont.svg @@ -0,0 +1,2671 @@ + + + + +Created by FontForge 20120731 at Mon Oct 24 17:37:40 2016 + By ,,, +Copyright Dave Gandy 2016. All rights reserved. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/book/FontAwesome/fonts/fontawesome-webfont.ttf b/book/FontAwesome/fonts/fontawesome-webfont.ttf new file mode 100644 index 00000000..35acda2f Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.ttf differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.woff b/book/FontAwesome/fonts/fontawesome-webfont.woff new file mode 100644 index 00000000..400014a4 Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.woff differ diff --git a/book/FontAwesome/fonts/fontawesome-webfont.woff2 b/book/FontAwesome/fonts/fontawesome-webfont.woff2 new file mode 100644 index 00000000..4d13fc60 Binary files /dev/null and b/book/FontAwesome/fonts/fontawesome-webfont.woff2 differ diff --git a/book/ayu-highlight.css b/book/ayu-highlight.css new file mode 100644 index 00000000..32c94322 --- /dev/null +++ b/book/ayu-highlight.css @@ -0,0 +1,78 @@ +/* +Based off of the Ayu theme +Original by Dempfi (https://github.com/dempfi/ayu) +*/ + +.hljs { + display: block; + overflow-x: auto; + background: #191f26; + color: #e6e1cf; +} + +.hljs-comment, +.hljs-quote { + color: #5c6773; + font-style: italic; +} + +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-attr, +.hljs-regexp, +.hljs-link, +.hljs-selector-id, +.hljs-selector-class { + color: #ff7733; +} + +.hljs-number, +.hljs-meta, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #ffee99; +} + +.hljs-string, +.hljs-bullet { + color: #b8cc52; +} + +.hljs-title, +.hljs-built_in, +.hljs-section { + color: #ffb454; +} + +.hljs-keyword, +.hljs-selector-tag, +.hljs-symbol { + color: #ff7733; +} + +.hljs-name { + color: #36a3d9; +} + +.hljs-tag { + color: #00568d; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-addition { + color: #91b362; +} + +.hljs-deletion { + color: #d96c75; +} diff --git a/book/book.js b/book/book.js new file mode 100644 index 00000000..aa12e7ec --- /dev/null +++ b/book/book.js @@ -0,0 +1,697 @@ +"use strict"; + +// Fix back button cache problem +window.onunload = function () { }; + +// Global variable, shared between modules +function playground_text(playground, hidden = true) { + let code_block = playground.querySelector("code"); + + if (window.ace && code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + return editor.getValue(); + } else if (hidden) { + return code_block.textContent; + } else { + return code_block.innerText; + } +} + +(function codeSnippets() { + function fetch_with_timeout(url, options, timeout = 6000) { + return Promise.race([ + fetch(url, options), + new Promise((_, reject) => setTimeout(() => reject(new Error('timeout')), timeout)) + ]); + } + + var playgrounds = Array.from(document.querySelectorAll(".playground")); + if (playgrounds.length > 0) { + fetch_with_timeout("https://play.rust-lang.org/meta/crates", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + }) + .then(response => response.json()) + .then(response => { + // get list of crates available in the rust playground + let playground_crates = response.crates.map(item => item["id"]); + playgrounds.forEach(block => handle_crate_list_update(block, playground_crates)); + }); + } + + function handle_crate_list_update(playground_block, playground_crates) { + // update the play buttons after receiving the response + update_play_button(playground_block, playground_crates); + + // and install on change listener to dynamically update ACE editors + if (window.ace) { + let code_block = playground_block.querySelector("code"); + if (code_block.classList.contains("editable")) { + let editor = window.ace.edit(code_block); + editor.addEventListener("change", function (e) { + update_play_button(playground_block, playground_crates); + }); + // add Ctrl-Enter command to execute rust code + editor.commands.addCommand({ + name: "run", + bindKey: { + win: "Ctrl-Enter", + mac: "Ctrl-Enter" + }, + exec: _editor => run_rust_code(playground_block) + }); + } + } + } + + // updates the visibility of play button based on `no_run` class and + // used crates vs ones available on https://play.rust-lang.org + function update_play_button(pre_block, playground_crates) { + var play_button = pre_block.querySelector(".play-button"); + + // skip if code is `no_run` + if (pre_block.querySelector('code').classList.contains("no_run")) { + play_button.classList.add("hidden"); + return; + } + + // get list of `extern crate`'s from snippet + var txt = playground_text(pre_block); + var re = /extern\s+crate\s+([a-zA-Z_0-9]+)\s*;/g; + var snippet_crates = []; + var item; + while (item = re.exec(txt)) { + snippet_crates.push(item[1]); + } + + // check if all used crates are available on play.rust-lang.org + var all_available = snippet_crates.every(function (elem) { + return playground_crates.indexOf(elem) > -1; + }); + + if (all_available) { + play_button.classList.remove("hidden"); + } else { + play_button.classList.add("hidden"); + } + } + + function run_rust_code(code_block) { + var result_block = code_block.querySelector(".result"); + if (!result_block) { + result_block = document.createElement('code'); + result_block.className = 'result hljs language-bash'; + + code_block.append(result_block); + } + + let text = playground_text(code_block); + let classes = code_block.querySelector('code').classList; + let edition = "2015"; + if(classes.contains("edition2018")) { + edition = "2018"; + } else if(classes.contains("edition2021")) { + edition = "2021"; + } + var params = { + version: "stable", + optimize: "0", + code: text, + edition: edition + }; + + if (text.indexOf("#![feature") !== -1) { + params.version = "nightly"; + } + + result_block.innerText = "Running..."; + + fetch_with_timeout("https://play.rust-lang.org/evaluate.json", { + headers: { + 'Content-Type': "application/json", + }, + method: 'POST', + mode: 'cors', + body: JSON.stringify(params) + }) + .then(response => response.json()) + .then(response => { + if (response.result.trim() === '') { + result_block.innerText = "No output"; + result_block.classList.add("result-no-output"); + } else { + result_block.innerText = response.result; + result_block.classList.remove("result-no-output"); + } + }) + .catch(error => result_block.innerText = "Playground Communication: " + error.message); + } + + // Syntax highlighting Configuration + hljs.configure({ + tabReplace: ' ', // 4 spaces + languages: [], // Languages used for auto-detection + }); + + let code_nodes = Array + .from(document.querySelectorAll('code')) + // Don't highlight `inline code` blocks in headers. + .filter(function (node) {return !node.parentElement.classList.contains("header"); }); + + if (window.ace) { + // language-rust class needs to be removed for editable + // blocks or highlightjs will capture events + code_nodes + .filter(function (node) {return node.classList.contains("editable"); }) + .forEach(function (block) { block.classList.remove('language-rust'); }); + + code_nodes + .filter(function (node) {return !node.classList.contains("editable"); }) + .forEach(function (block) { hljs.highlightBlock(block); }); + } else { + code_nodes.forEach(function (block) { hljs.highlightBlock(block); }); + } + + // Adding the hljs class gives code blocks the color css + // even if highlighting doesn't apply + code_nodes.forEach(function (block) { block.classList.add('hljs'); }); + + Array.from(document.querySelectorAll("code.hljs")).forEach(function (block) { + + var lines = Array.from(block.querySelectorAll('.boring')); + // If no lines were hidden, return + if (!lines.length) { return; } + block.classList.add("hide-boring"); + + var buttons = document.createElement('div'); + buttons.className = 'buttons'; + buttons.innerHTML = ""; + + // add expand button + var pre_block = block.parentNode; + pre_block.insertBefore(buttons, pre_block.firstChild); + + pre_block.querySelector('.buttons').addEventListener('click', function (e) { + if (e.target.classList.contains('fa-eye')) { + e.target.classList.remove('fa-eye'); + e.target.classList.add('fa-eye-slash'); + e.target.title = 'Hide lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.remove('hide-boring'); + } else if (e.target.classList.contains('fa-eye-slash')) { + e.target.classList.remove('fa-eye-slash'); + e.target.classList.add('fa-eye'); + e.target.title = 'Show hidden lines'; + e.target.setAttribute('aria-label', e.target.title); + + block.classList.add('hide-boring'); + } + }); + }); + + if (window.playground_copyable) { + Array.from(document.querySelectorAll('pre code')).forEach(function (block) { + var pre_block = block.parentNode; + if (!pre_block.classList.contains('playground')) { + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var clipButton = document.createElement('button'); + clipButton.className = 'fa fa-copy clip-button'; + clipButton.title = 'Copy to clipboard'; + clipButton.setAttribute('aria-label', clipButton.title); + clipButton.innerHTML = ''; + + buttons.insertBefore(clipButton, buttons.firstChild); + } + }); + } + + // Process playground code blocks + Array.from(document.querySelectorAll(".playground")).forEach(function (pre_block) { + // Add play button + var buttons = pre_block.querySelector(".buttons"); + if (!buttons) { + buttons = document.createElement('div'); + buttons.className = 'buttons'; + pre_block.insertBefore(buttons, pre_block.firstChild); + } + + var runCodeButton = document.createElement('button'); + runCodeButton.className = 'fa fa-play play-button'; + runCodeButton.hidden = true; + runCodeButton.title = 'Run this code'; + runCodeButton.setAttribute('aria-label', runCodeButton.title); + + buttons.insertBefore(runCodeButton, buttons.firstChild); + runCodeButton.addEventListener('click', function (e) { + run_rust_code(pre_block); + }); + + if (window.playground_copyable) { + var copyCodeClipboardButton = document.createElement('button'); + copyCodeClipboardButton.className = 'fa fa-copy clip-button'; + copyCodeClipboardButton.innerHTML = ''; + copyCodeClipboardButton.title = 'Copy to clipboard'; + copyCodeClipboardButton.setAttribute('aria-label', copyCodeClipboardButton.title); + + buttons.insertBefore(copyCodeClipboardButton, buttons.firstChild); + } + + let code_block = pre_block.querySelector("code"); + if (window.ace && code_block.classList.contains("editable")) { + var undoChangesButton = document.createElement('button'); + undoChangesButton.className = 'fa fa-history reset-button'; + undoChangesButton.title = 'Undo changes'; + undoChangesButton.setAttribute('aria-label', undoChangesButton.title); + + buttons.insertBefore(undoChangesButton, buttons.firstChild); + + undoChangesButton.addEventListener('click', function () { + let editor = window.ace.edit(code_block); + editor.setValue(editor.originalCode); + editor.clearSelection(); + }); + } + }); +})(); + +(function themes() { + var html = document.querySelector('html'); + var themeToggleButton = document.getElementById('theme-toggle'); + var themePopup = document.getElementById('theme-list'); + var themeColorMetaTag = document.querySelector('meta[name="theme-color"]'); + var stylesheets = { + ayuHighlight: document.querySelector("[href$='ayu-highlight.css']"), + tomorrowNight: document.querySelector("[href$='tomorrow-night.css']"), + highlight: document.querySelector("[href$='highlight.css']"), + }; + + function showThemes() { + themePopup.style.display = 'block'; + themeToggleButton.setAttribute('aria-expanded', true); + themePopup.querySelector("button#" + get_theme()).focus(); + } + + function updateThemeSelected() { + themePopup.querySelectorAll('.theme-selected').forEach(function (el) { + el.classList.remove('theme-selected'); + }); + themePopup.querySelector("button#" + get_theme()).classList.add('theme-selected'); + } + + function hideThemes() { + themePopup.style.display = 'none'; + themeToggleButton.setAttribute('aria-expanded', false); + themeToggleButton.focus(); + } + + function get_theme() { + var theme; + try { theme = localStorage.getItem('mdbook-theme'); } catch (e) { } + if (theme === null || theme === undefined) { + return default_theme; + } else { + return theme; + } + } + + function set_theme(theme, store = true) { + let ace_theme; + + if (theme == 'coal' || theme == 'navy') { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = false; + stylesheets.highlight.disabled = true; + + ace_theme = "ace/theme/tomorrow_night"; + } else if (theme == 'ayu') { + stylesheets.ayuHighlight.disabled = false; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = true; + ace_theme = "ace/theme/tomorrow_night"; + } else { + stylesheets.ayuHighlight.disabled = true; + stylesheets.tomorrowNight.disabled = true; + stylesheets.highlight.disabled = false; + ace_theme = "ace/theme/dawn"; + } + + setTimeout(function () { + themeColorMetaTag.content = getComputedStyle(document.documentElement).backgroundColor; + }, 1); + + if (window.ace && window.editors) { + window.editors.forEach(function (editor) { + editor.setTheme(ace_theme); + }); + } + + var previousTheme = get_theme(); + + if (store) { + try { localStorage.setItem('mdbook-theme', theme); } catch (e) { } + } + + html.classList.remove(previousTheme); + html.classList.add(theme); + updateThemeSelected(); + } + + // Set theme + var theme = get_theme(); + + set_theme(theme, false); + + themeToggleButton.addEventListener('click', function () { + if (themePopup.style.display === 'block') { + hideThemes(); + } else { + showThemes(); + } + }); + + themePopup.addEventListener('click', function (e) { + var theme; + if (e.target.className === "theme") { + theme = e.target.id; + } else if (e.target.parentElement.className === "theme") { + theme = e.target.parentElement.id; + } else { + return; + } + set_theme(theme); + }); + + themePopup.addEventListener('focusout', function(e) { + // e.relatedTarget is null in Safari and Firefox on macOS (see workaround below) + if (!!e.relatedTarget && !themeToggleButton.contains(e.relatedTarget) && !themePopup.contains(e.relatedTarget)) { + hideThemes(); + } + }); + + // Should not be needed, but it works around an issue on macOS & iOS: https://github.com/rust-lang/mdBook/issues/628 + document.addEventListener('click', function(e) { + if (themePopup.style.display === 'block' && !themeToggleButton.contains(e.target) && !themePopup.contains(e.target)) { + hideThemes(); + } + }); + + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (!themePopup.contains(e.target)) { return; } + + switch (e.key) { + case 'Escape': + e.preventDefault(); + hideThemes(); + break; + case 'ArrowUp': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.previousElementSibling) { + li.previousElementSibling.querySelector('button').focus(); + } + break; + case 'ArrowDown': + e.preventDefault(); + var li = document.activeElement.parentElement; + if (li && li.nextElementSibling) { + li.nextElementSibling.querySelector('button').focus(); + } + break; + case 'Home': + e.preventDefault(); + themePopup.querySelector('li:first-child button').focus(); + break; + case 'End': + e.preventDefault(); + themePopup.querySelector('li:last-child button').focus(); + break; + } + }); +})(); + +(function sidebar() { + var body = document.querySelector("body"); + var sidebar = document.getElementById("sidebar"); + var sidebarLinks = document.querySelectorAll('#sidebar a'); + var sidebarToggleButton = document.getElementById("sidebar-toggle"); + var sidebarResizeHandle = document.getElementById("sidebar-resize-handle"); + var firstContact = null; + + function showSidebar() { + body.classList.remove('sidebar-hidden') + body.classList.add('sidebar-visible'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', 0); + }); + sidebarToggleButton.setAttribute('aria-expanded', true); + sidebar.setAttribute('aria-hidden', false); + try { localStorage.setItem('mdbook-sidebar', 'visible'); } catch (e) { } + } + + + var sidebarAnchorToggles = document.querySelectorAll('#sidebar a.toggle'); + + function toggleSection(ev) { + ev.currentTarget.parentElement.classList.toggle('expanded'); + } + + Array.from(sidebarAnchorToggles).forEach(function (el) { + el.addEventListener('click', toggleSection); + }); + + function hideSidebar() { + body.classList.remove('sidebar-visible') + body.classList.add('sidebar-hidden'); + Array.from(sidebarLinks).forEach(function (link) { + link.setAttribute('tabIndex', -1); + }); + sidebarToggleButton.setAttribute('aria-expanded', false); + sidebar.setAttribute('aria-hidden', true); + try { localStorage.setItem('mdbook-sidebar', 'hidden'); } catch (e) { } + } + + // Toggle sidebar + sidebarToggleButton.addEventListener('click', function sidebarToggle() { + if (body.classList.contains("sidebar-hidden")) { + var current_width = parseInt( + document.documentElement.style.getPropertyValue('--sidebar-width'), 10); + if (current_width < 150) { + document.documentElement.style.setProperty('--sidebar-width', '150px'); + } + showSidebar(); + } else if (body.classList.contains("sidebar-visible")) { + hideSidebar(); + } else { + if (getComputedStyle(sidebar)['transform'] === 'none') { + hideSidebar(); + } else { + showSidebar(); + } + } + }); + + sidebarResizeHandle.addEventListener('mousedown', initResize, false); + + function initResize(e) { + window.addEventListener('mousemove', resize, false); + window.addEventListener('mouseup', stopResize, false); + body.classList.add('sidebar-resizing'); + } + function resize(e) { + var pos = (e.clientX - sidebar.offsetLeft); + if (pos < 20) { + hideSidebar(); + } else { + if (body.classList.contains("sidebar-hidden")) { + showSidebar(); + } + pos = Math.min(pos, window.innerWidth - 100); + document.documentElement.style.setProperty('--sidebar-width', pos + 'px'); + } + } + //on mouseup remove windows functions mousemove & mouseup + function stopResize(e) { + body.classList.remove('sidebar-resizing'); + window.removeEventListener('mousemove', resize, false); + window.removeEventListener('mouseup', stopResize, false); + } + + document.addEventListener('touchstart', function (e) { + firstContact = { + x: e.touches[0].clientX, + time: Date.now() + }; + }, { passive: true }); + + document.addEventListener('touchmove', function (e) { + if (!firstContact) + return; + + var curX = e.touches[0].clientX; + var xDiff = curX - firstContact.x, + tDiff = Date.now() - firstContact.time; + + if (tDiff < 250 && Math.abs(xDiff) >= 150) { + if (xDiff >= 0 && firstContact.x < Math.min(document.body.clientWidth * 0.25, 300)) + showSidebar(); + else if (xDiff < 0 && curX < 300) + hideSidebar(); + + firstContact = null; + } + }, { passive: true }); +})(); + +(function chapterNavigation() { + document.addEventListener('keydown', function (e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey) { return; } + if (window.search && window.search.hasFocus()) { return; } + var html = document.querySelector('html'); + + function next() { + var nextButton = document.querySelector('.nav-chapters.next'); + if (nextButton) { + window.location.href = nextButton.href; + } + } + function prev() { + var previousButton = document.querySelector('.nav-chapters.previous'); + if (previousButton) { + window.location.href = previousButton.href; + } + } + switch (e.key) { + case 'ArrowRight': + e.preventDefault(); + if (html.dir == 'rtl') { + prev(); + } else { + next(); + } + break; + case 'ArrowLeft': + e.preventDefault(); + if (html.dir == 'rtl') { + next(); + } else { + prev(); + } + break; + } + }); +})(); + +(function clipboard() { + var clipButtons = document.querySelectorAll('.clip-button'); + + function hideTooltip(elem) { + elem.firstChild.innerText = ""; + elem.className = 'fa fa-copy clip-button'; + } + + function showTooltip(elem, msg) { + elem.firstChild.innerText = msg; + elem.className = 'fa fa-copy tooltipped'; + } + + var clipboardSnippets = new ClipboardJS('.clip-button', { + text: function (trigger) { + hideTooltip(trigger); + let playground = trigger.closest("pre"); + return playground_text(playground, false); + } + }); + + Array.from(clipButtons).forEach(function (clipButton) { + clipButton.addEventListener('mouseout', function (e) { + hideTooltip(e.currentTarget); + }); + }); + + clipboardSnippets.on('success', function (e) { + e.clearSelection(); + showTooltip(e.trigger, "Copied!"); + }); + + clipboardSnippets.on('error', function (e) { + showTooltip(e.trigger, "Clipboard error!"); + }); +})(); + +(function scrollToTop () { + var menuTitle = document.querySelector('.menu-title'); + + menuTitle.addEventListener('click', function () { + document.scrollingElement.scrollTo({ top: 0, behavior: 'smooth' }); + }); +})(); + +(function controllMenu() { + var menu = document.getElementById('menu-bar'); + + (function controllPosition() { + var scrollTop = document.scrollingElement.scrollTop; + var prevScrollTop = scrollTop; + var minMenuY = -menu.clientHeight - 50; + // When the script loads, the page can be at any scroll (e.g. if you reforesh it). + menu.style.top = scrollTop + 'px'; + // Same as parseInt(menu.style.top.slice(0, -2), but faster + var topCache = menu.style.top.slice(0, -2); + menu.classList.remove('sticky'); + var stickyCache = false; // Same as menu.classList.contains('sticky'), but faster + document.addEventListener('scroll', function () { + scrollTop = Math.max(document.scrollingElement.scrollTop, 0); + // `null` means that it doesn't need to be updated + var nextSticky = null; + var nextTop = null; + var scrollDown = scrollTop > prevScrollTop; + var menuPosAbsoluteY = topCache - scrollTop; + if (scrollDown) { + nextSticky = false; + if (menuPosAbsoluteY > 0) { + nextTop = prevScrollTop; + } + } else { + if (menuPosAbsoluteY > 0) { + nextSticky = true; + } else if (menuPosAbsoluteY < minMenuY) { + nextTop = prevScrollTop + minMenuY; + } + } + if (nextSticky === true && stickyCache === false) { + menu.classList.add('sticky'); + stickyCache = true; + } else if (nextSticky === false && stickyCache === true) { + menu.classList.remove('sticky'); + stickyCache = false; + } + if (nextTop !== null) { + menu.style.top = nextTop + 'px'; + topCache = nextTop; + } + prevScrollTop = scrollTop; + }, { passive: true }); + })(); + (function controllBorder() { + function updateBorder() { + if (menu.offsetTop === 0) { + menu.classList.remove('bordered'); + } else { + menu.classList.add('bordered'); + } + } + updateBorder(); + document.addEventListener('scroll', updateBorder, { passive: true }); + })(); +})(); diff --git a/book/clipboard.min.js b/book/clipboard.min.js new file mode 100644 index 00000000..02c549e3 --- /dev/null +++ b/book/clipboard.min.js @@ -0,0 +1,7 @@ +/*! + * clipboard.js v2.0.4 + * https://zenorocha.github.io/clipboard.js + * + * Licensed MIT © Zeno Rocha + */ +!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.ClipboardJS=e():t.ClipboardJS=e()}(this,function(){return function(n){var o={};function r(t){if(o[t])return o[t].exports;var e=o[t]={i:t,l:!1,exports:{}};return n[t].call(e.exports,e,e.exports,r),e.l=!0,e.exports}return r.m=n,r.c=o,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(e,t){if(1&t&&(e=r(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)r.d(n,o,function(t){return e[t]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,n){"use strict";var r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},i=function(){function o(t,e){for(var n=0;n .hljs { + color: var(--links); +} + +/* + body-container is necessary because mobile browsers don't seem to like + overflow-x on the body tag when there is a tag. +*/ +#body-container { + /* + This is used when the sidebar pushes the body content off the side of + the screen on small screens. Without it, dragging on mobile Safari + will want to reposition the viewport in a weird way. + */ + overflow-x: clip; +} + +/* Menu Bar */ + +#menu-bar, +#menu-bar-hover-placeholder { + z-index: 101; + margin: auto calc(0px - var(--page-padding)); +} +#menu-bar { + position: relative; + display: flex; + flex-wrap: wrap; + background-color: var(--bg); + border-block-end-color: var(--bg); + border-block-end-width: 1px; + border-block-end-style: solid; +} +#menu-bar.sticky, +.js #menu-bar-hover-placeholder:hover + #menu-bar, +.js #menu-bar:hover, +.js.sidebar-visible #menu-bar { + position: -webkit-sticky; + position: sticky; + top: 0 !important; +} +#menu-bar-hover-placeholder { + position: sticky; + position: -webkit-sticky; + top: 0; + height: var(--menu-bar-height); +} +#menu-bar.bordered { + border-block-end-color: var(--table-border-color); +} +#menu-bar i, #menu-bar .icon-button { + position: relative; + padding: 0 8px; + z-index: 10; + line-height: var(--menu-bar-height); + cursor: pointer; + transition: color 0.5s; +} +@media only screen and (max-width: 420px) { + #menu-bar i, #menu-bar .icon-button { + padding: 0 5px; + } +} + +.icon-button { + border: none; + background: none; + padding: 0; + color: inherit; +} +.icon-button i { + margin: 0; +} + +.right-buttons { + margin: 0 15px; +} +.right-buttons a { + text-decoration: none; +} + +.left-buttons { + display: flex; + margin: 0 5px; +} +.no-js .left-buttons button { + display: none; +} + +.menu-title { + display: inline-block; + font-weight: 200; + font-size: 2.4rem; + line-height: var(--menu-bar-height); + text-align: center; + margin: 0; + flex: 1; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; +} +.js .menu-title { + cursor: pointer; +} + +.menu-bar, +.menu-bar:visited, +.nav-chapters, +.nav-chapters:visited, +.mobile-nav-chapters, +.mobile-nav-chapters:visited, +.menu-bar .icon-button, +.menu-bar a i { + color: var(--icons); +} + +.menu-bar i:hover, +.menu-bar .icon-button:hover, +.nav-chapters:hover, +.mobile-nav-chapters i:hover { + color: var(--icons-hover); +} + +/* Nav Icons */ + +.nav-chapters { + font-size: 2.5em; + text-align: center; + text-decoration: none; + + position: fixed; + top: 0; + bottom: 0; + margin: 0; + max-width: 150px; + min-width: 90px; + + display: flex; + justify-content: center; + align-content: center; + flex-direction: column; + + transition: color 0.5s, background-color 0.5s; +} + +.nav-chapters:hover { + text-decoration: none; + background-color: var(--theme-hover); + transition: background-color 0.15s, color 0.15s; +} + +.nav-wrapper { + margin-block-start: 50px; + display: none; +} + +.mobile-nav-chapters { + font-size: 2.5em; + text-align: center; + text-decoration: none; + width: 90px; + border-radius: 5px; + background-color: var(--sidebar-bg); +} + +/* Only Firefox supports flow-relative values */ +.previous { float: left; } +[dir=rtl] .previous { float: right; } + +/* Only Firefox supports flow-relative values */ +.next { + float: right; + right: var(--page-padding); +} +[dir=rtl] .next { + float: left; + right: unset; + left: var(--page-padding); +} + +/* Use the correct buttons for RTL layouts*/ +[dir=rtl] .previous i.fa-angle-left:before {content:"\f105";} +[dir=rtl] .next i.fa-angle-right:before { content:"\f104"; } + +@media only screen and (max-width: 1080px) { + .nav-wide-wrapper { display: none; } + .nav-wrapper { display: block; } +} + +/* sidebar-visible */ +@media only screen and (max-width: 1380px) { + #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wide-wrapper { display: none; } + #sidebar-toggle-anchor:checked ~ .page-wrapper .nav-wrapper { display: block; } +} + +/* Inline code */ + +:not(pre) > .hljs { + display: inline; + padding: 0.1em 0.3em; + border-radius: 3px; +} + +:not(pre):not(a) > .hljs { + color: var(--inline-code-color); + overflow-x: initial; +} + +a:hover > .hljs { + text-decoration: underline; +} + +pre { + position: relative; +} +pre > .buttons { + position: absolute; + z-index: 100; + right: 0px; + top: 2px; + margin: 0px; + padding: 2px 0px; + + color: var(--sidebar-fg); + cursor: pointer; + visibility: hidden; + opacity: 0; + transition: visibility 0.1s linear, opacity 0.1s linear; +} +pre:hover > .buttons { + visibility: visible; + opacity: 1 +} +pre > .buttons :hover { + color: var(--sidebar-active); + border-color: var(--icons-hover); + background-color: var(--theme-hover); +} +pre > .buttons i { + margin-inline-start: 8px; +} +pre > .buttons button { + cursor: inherit; + margin: 0px 5px; + padding: 3px 5px; + font-size: 14px; + + border-style: solid; + border-width: 1px; + border-radius: 4px; + border-color: var(--icons); + background-color: var(--theme-popup-bg); + transition: 100ms; + transition-property: color,border-color,background-color; + color: var(--icons); +} +@media (pointer: coarse) { + pre > .buttons button { + /* On mobile, make it easier to tap buttons. */ + padding: 0.3rem 1rem; + } + + .sidebar-resize-indicator { + /* Hide resize indicator on devices with limited accuracy */ + display: none; + } +} +pre > code { + display: block; + padding: 1rem; +} + +/* FIXME: ACE editors overlap their buttons because ACE does absolute + positioning within the code block which breaks padding. The only solution I + can think of is to move the padding to the outer pre tag (or insert a div + wrapper), but that would require fixing a whole bunch of CSS rules. +*/ +.hljs.ace_editor { + padding: 0rem 0rem; +} + +pre > .result { + margin-block-start: 10px; +} + +/* Search */ + +#searchresults a { + text-decoration: none; +} + +mark { + border-radius: 2px; + padding-block-start: 0; + padding-block-end: 1px; + padding-inline-start: 3px; + padding-inline-end: 3px; + margin-block-start: 0; + margin-block-end: -1px; + margin-inline-start: -3px; + margin-inline-end: -3px; + background-color: var(--search-mark-bg); + transition: background-color 300ms linear; + cursor: pointer; +} + +mark.fade-out { + background-color: rgba(0,0,0,0) !important; + cursor: auto; +} + +.searchbar-outer { + margin-inline-start: auto; + margin-inline-end: auto; + max-width: var(--content-max-width); +} + +#searchbar { + width: 100%; + margin-block-start: 5px; + margin-block-end: 0; + margin-inline-start: auto; + margin-inline-end: auto; + padding: 10px 16px; + transition: box-shadow 300ms ease-in-out; + border: 1px solid var(--searchbar-border-color); + border-radius: 3px; + background-color: var(--searchbar-bg); + color: var(--searchbar-fg); +} +#searchbar:focus, +#searchbar.active { + box-shadow: 0 0 3px var(--searchbar-shadow-color); +} + +.searchresults-header { + font-weight: bold; + font-size: 1em; + padding-block-start: 18px; + padding-block-end: 0; + padding-inline-start: 5px; + padding-inline-end: 0; + color: var(--searchresults-header-fg); +} + +.searchresults-outer { + margin-inline-start: auto; + margin-inline-end: auto; + max-width: var(--content-max-width); + border-block-end: 1px dashed var(--searchresults-border-color); +} + +ul#searchresults { + list-style: none; + padding-inline-start: 20px; +} +ul#searchresults li { + margin: 10px 0px; + padding: 2px; + border-radius: 2px; +} +ul#searchresults li.focus { + background-color: var(--searchresults-li-bg); +} +ul#searchresults span.teaser { + display: block; + clear: both; + margin-block-start: 5px; + margin-block-end: 0; + margin-inline-start: 20px; + margin-inline-end: 0; + font-size: 0.8em; +} +ul#searchresults span.teaser em { + font-weight: bold; + font-style: normal; +} + +/* Sidebar */ + +.sidebar { + position: fixed; + left: 0; + top: 0; + bottom: 0; + width: var(--sidebar-width); + font-size: 0.875em; + box-sizing: border-box; + -webkit-overflow-scrolling: touch; + overscroll-behavior-y: contain; + background-color: var(--sidebar-bg); + color: var(--sidebar-fg); +} +[dir=rtl] .sidebar { left: unset; right: 0; } +.sidebar-resizing { + -moz-user-select: none; + -webkit-user-select: none; + -ms-user-select: none; + user-select: none; +} +.no-js .sidebar, +.js:not(.sidebar-resizing) .sidebar { + transition: transform 0.3s; /* Animation: slide away */ +} +.sidebar code { + line-height: 2em; +} +.sidebar .sidebar-scrollbox { + overflow-y: auto; + position: absolute; + top: 0; + bottom: 0; + left: 0; + right: 0; + padding: 10px 10px; +} +.sidebar .sidebar-resize-handle { + position: absolute; + cursor: col-resize; + width: 0; + right: calc(var(--sidebar-resize-indicator-width) * -1); + top: 0; + bottom: 0; + display: flex; + align-items: center; +} + +.sidebar-resize-handle .sidebar-resize-indicator { + width: 100%; + height: 12px; + background-color: var(--icons); + margin-inline-start: var(--sidebar-resize-indicator-space); +} + +[dir=rtl] .sidebar .sidebar-resize-handle { + left: calc(var(--sidebar-resize-indicator-width) * -1); + right: unset; +} +.js .sidebar .sidebar-resize-handle { + cursor: col-resize; + width: calc(var(--sidebar-resize-indicator-width) - var(--sidebar-resize-indicator-space)); +} +/* sidebar-hidden */ +#sidebar-toggle-anchor:not(:checked) ~ .sidebar { + transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width))); + z-index: -1; +} +[dir=rtl] #sidebar-toggle-anchor:not(:checked) ~ .sidebar { + transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width))); +} +.sidebar::-webkit-scrollbar { + background: var(--sidebar-bg); +} +.sidebar::-webkit-scrollbar-thumb { + background: var(--scrollbar); +} + +/* sidebar-visible */ +#sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: translateX(calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width))); +} +[dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: translateX(calc(0px - var(--sidebar-width) - var(--sidebar-resize-indicator-width))); +} +@media only screen and (min-width: 620px) { + #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: none; + margin-inline-start: calc(var(--sidebar-width) + var(--sidebar-resize-indicator-width)); + } + [dir=rtl] #sidebar-toggle-anchor:checked ~ .page-wrapper { + transform: none; + } +} + +.chapter { + list-style: none outside none; + padding-inline-start: 0; + line-height: 2.2em; +} + +.chapter ol { + width: 100%; +} + +.chapter li { + display: flex; + color: var(--sidebar-non-existant); +} +.chapter li a { + display: block; + padding: 0; + text-decoration: none; + color: var(--sidebar-fg); +} + +.chapter li a:hover { + color: var(--sidebar-active); +} + +.chapter li a.active { + color: var(--sidebar-active); +} + +.chapter li > a.toggle { + cursor: pointer; + display: block; + margin-inline-start: auto; + padding: 0 10px; + user-select: none; + opacity: 0.68; +} + +.chapter li > a.toggle div { + transition: transform 0.5s; +} + +/* collapse the section */ +.chapter li:not(.expanded) + li > ol { + display: none; +} + +.chapter li.chapter-item { + line-height: 1.5em; + margin-block-start: 0.6em; +} + +.chapter li.expanded > a.toggle div { + transform: rotate(90deg); +} + +.spacer { + width: 100%; + height: 3px; + margin: 5px 0px; +} +.chapter .spacer { + background-color: var(--sidebar-spacer); +} + +@media (-moz-touch-enabled: 1), (pointer: coarse) { + .chapter li a { padding: 5px 0; } + .spacer { margin: 10px 0; } +} + +.section { + list-style: none outside none; + padding-inline-start: 20px; + line-height: 1.9em; +} + +/* Theme Menu Popup */ + +.theme-popup { + position: absolute; + left: 10px; + top: var(--menu-bar-height); + z-index: 1000; + border-radius: 4px; + font-size: 0.7em; + color: var(--fg); + background: var(--theme-popup-bg); + border: 1px solid var(--theme-popup-border); + margin: 0; + padding: 0; + list-style: none; + display: none; + /* Don't let the children's background extend past the rounded corners. */ + overflow: hidden; +} +[dir=rtl] .theme-popup { left: unset; right: 10px; } +.theme-popup .default { + color: var(--icons); +} +.theme-popup .theme { + width: 100%; + border: 0; + margin: 0; + padding: 2px 20px; + line-height: 25px; + white-space: nowrap; + text-align: start; + cursor: pointer; + color: inherit; + background: inherit; + font-size: inherit; +} +.theme-popup .theme:hover { + background-color: var(--theme-hover); +} + +.theme-selected::before { + display: inline-block; + content: "✓"; + margin-inline-start: -14px; + width: 14px; +} diff --git a/book/css/general.css b/book/css/general.css new file mode 100644 index 00000000..7670b087 --- /dev/null +++ b/book/css/general.css @@ -0,0 +1,232 @@ +/* Base styles and content styles */ + +:root { + /* Browser default font-size is 16px, this way 1 rem = 10px */ + font-size: 62.5%; + color-scheme: var(--color-scheme); +} + +html { + font-family: "Open Sans", sans-serif; + color: var(--fg); + background-color: var(--bg); + text-size-adjust: none; + -webkit-text-size-adjust: none; +} + +body { + margin: 0; + font-size: 1.6rem; + overflow-x: hidden; +} + +code { + font-family: var(--mono-font) !important; + font-size: var(--code-font-size); + direction: ltr !important; +} + +/* make long words/inline code not x overflow */ +main { + overflow-wrap: break-word; +} + +/* make wide tables scroll if they overflow */ +.table-wrapper { + overflow-x: auto; +} + +/* Don't change font size in headers. */ +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + font-size: unset; +} + +.left { float: left; } +.right { float: right; } +.boring { opacity: 0.6; } +.hide-boring .boring { display: none; } +.hidden { display: none !important; } + +h2, h3 { margin-block-start: 2.5em; } +h4, h5 { margin-block-start: 2em; } + +.header + .header h3, +.header + .header h4, +.header + .header h5 { + margin-block-start: 1em; +} + +h1:target::before, +h2:target::before, +h3:target::before, +h4:target::before, +h5:target::before, +h6:target::before { + display: inline-block; + content: "»"; + margin-inline-start: -30px; + width: 30px; +} + +/* This is broken on Safari as of version 14, but is fixed + in Safari Technology Preview 117 which I think will be Safari 14.2. + https://bugs.webkit.org/show_bug.cgi?id=218076 +*/ +:target { + /* Safari does not support logical properties */ + scroll-margin-top: calc(var(--menu-bar-height) + 0.5em); +} + +.page { + outline: 0; + padding: 0 var(--page-padding); + margin-block-start: calc(0px - var(--menu-bar-height)); /* Compensate for the #menu-bar-hover-placeholder */ +} +.page-wrapper { + box-sizing: border-box; + background-color: var(--bg); +} +.no-js .page-wrapper, +.js:not(.sidebar-resizing) .page-wrapper { + transition: margin-left 0.3s ease, transform 0.3s ease; /* Animation: slide away */ +} +[dir=rtl] .js:not(.sidebar-resizing) .page-wrapper { + transition: margin-right 0.3s ease, transform 0.3s ease; /* Animation: slide away */ +} + +.content { + overflow-y: auto; + padding: 0 5px 50px 5px; +} +.content main { + margin-inline-start: auto; + margin-inline-end: auto; + max-width: var(--content-max-width); +} +.content p { line-height: 1.45em; } +.content ol { line-height: 1.45em; } +.content ul { line-height: 1.45em; } +.content a { text-decoration: none; } +.content a:hover { text-decoration: underline; } +.content img, .content video { max-width: 100%; } +.content .header:link, +.content .header:visited { + color: var(--fg); +} +.content .header:link, +.content .header:visited:hover { + text-decoration: none; +} + +table { + margin: 0 auto; + border-collapse: collapse; +} +table td { + padding: 3px 20px; + border: 1px var(--table-border-color) solid; +} +table thead { + background: var(--table-header-bg); +} +table thead td { + font-weight: 700; + border: none; +} +table thead th { + padding: 3px 20px; +} +table thead tr { + border: 1px var(--table-header-bg) solid; +} +/* Alternate background colors for rows */ +table tbody tr:nth-child(2n) { + background: var(--table-alternate-bg); +} + + +blockquote { + margin: 20px 0; + padding: 0 20px; + color: var(--fg); + background-color: var(--quote-bg); + border-block-start: .1em solid var(--quote-border); + border-block-end: .1em solid var(--quote-border); +} + +.warning { + margin: 20px; + padding: 0 20px; + border-inline-start: 2px solid var(--warning-border); +} + +.warning:before { + position: absolute; + width: 3rem; + height: 3rem; + margin-inline-start: calc(-1.5rem - 21px); + content: "ⓘ"; + text-align: center; + background-color: var(--bg); + color: var(--warning-border); + font-weight: bold; + font-size: 2rem; +} + +blockquote .warning:before { + background-color: var(--quote-bg); +} + +kbd { + background-color: var(--table-border-color); + border-radius: 4px; + border: solid 1px var(--theme-popup-border); + box-shadow: inset 0 -1px 0 var(--theme-hover); + display: inline-block; + font-size: var(--code-font-size); + font-family: var(--mono-font); + line-height: 10px; + padding: 4px 5px; + vertical-align: middle; +} + +:not(.footnote-definition) + .footnote-definition, +.footnote-definition + :not(.footnote-definition) { + margin-block-start: 2em; +} +.footnote-definition { + font-size: 0.9em; + margin: 0.5em 0; +} +.footnote-definition p { + display: inline; +} + +.tooltiptext { + position: absolute; + visibility: hidden; + color: #fff; + background-color: #333; + transform: translateX(-50%); /* Center by moving tooltip 50% of its width left */ + left: -8px; /* Half of the width of the icon */ + top: -35px; + font-size: 0.8em; + text-align: center; + border-radius: 6px; + padding: 5px 8px; + margin: 5px; + z-index: 1000; +} +.tooltipped .tooltiptext { + visibility: visible; +} + +.chapter li.part-title { + color: var(--sidebar-fg); + margin: 5px 0px; + font-weight: bold; +} + +.result-no-output { + font-style: italic; +} diff --git a/book/css/print.css b/book/css/print.css new file mode 100644 index 00000000..80ec3a54 --- /dev/null +++ b/book/css/print.css @@ -0,0 +1,50 @@ + +#sidebar, +#menu-bar, +.nav-chapters, +.mobile-nav-chapters { + display: none; +} + +#page-wrapper.page-wrapper { + transform: none !important; + margin-inline-start: 0px; + overflow-y: initial; +} + +#content { + max-width: none; + margin: 0; + padding: 0; +} + +.page { + overflow-y: initial; +} + +code { + direction: ltr !important; +} + +pre > .buttons { + z-index: 2; +} + +a, a:visited, a:active, a:hover { + color: #4183c4; + text-decoration: none; +} + +h1, h2, h3, h4, h5, h6 { + page-break-inside: avoid; + page-break-after: avoid; +} + +pre, code { + page-break-inside: avoid; + white-space: pre-wrap; +} + +.fa { + display: none !important; +} diff --git a/book/css/variables.css b/book/css/variables.css new file mode 100644 index 00000000..0da55e8c --- /dev/null +++ b/book/css/variables.css @@ -0,0 +1,279 @@ + +/* Globals */ + +:root { + --sidebar-width: 300px; + --sidebar-resize-indicator-width: 8px; + --sidebar-resize-indicator-space: 2px; + --page-padding: 15px; + --content-max-width: 750px; + --menu-bar-height: 50px; + --mono-font: "Source Code Pro", Consolas, "Ubuntu Mono", Menlo, "DejaVu Sans Mono", monospace, monospace; + --code-font-size: 0.875em /* please adjust the ace font size accordingly in editor.js */ +} + +/* Themes */ + +.ayu { + --bg: hsl(210, 25%, 8%); + --fg: #c5c5c5; + + --sidebar-bg: #14191f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #5c6773; + --sidebar-active: #ffb454; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #0096cf; + + --inline-code-color: #ffb454; + + --theme-popup-bg: #14191f; + --theme-popup-border: #5c6773; + --theme-hover: #191f26; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(210, 25%, 13%); + --table-header-bg: hsl(210, 25%, 28%); + --table-alternate-bg: hsl(210, 25%, 11%); + + --searchbar-border-color: #848484; + --searchbar-bg: #424242; + --searchbar-fg: #fff; + --searchbar-shadow-color: #d4c89f; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #252932; + --search-mark-bg: #e3b171; + + --color-scheme: dark; +} + +.coal { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); + + --icons: #43484d; + --icons-hover: #b3c0cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6; + + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; + + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; + + --color-scheme: dark; +} + +.light { + --bg: hsl(0, 0%, 100%); + --fg: hsl(0, 0%, 0%); + + --sidebar-bg: #fafafa; + --sidebar-fg: hsl(0, 0%, 0%); + --sidebar-non-existant: #aaaaaa; + --sidebar-active: #1f1fff; + --sidebar-spacer: #f4f4f4; + + --scrollbar: #8F8F8F; + + --icons: #747474; + --icons-hover: #000000; + + --links: #20609f; + + --inline-code-color: #301900; + + --theme-popup-bg: #fafafa; + --theme-popup-border: #cccccc; + --theme-hover: #e6e6e6; + + --quote-bg: hsl(197, 37%, 96%); + --quote-border: hsl(197, 37%, 91%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(0, 0%, 95%); + --table-header-bg: hsl(0, 0%, 80%); + --table-alternate-bg: hsl(0, 0%, 97%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #e4f2fe; + --search-mark-bg: #a2cff5; + + --color-scheme: light; +} + +.navy { + --bg: hsl(226, 23%, 11%); + --fg: #bcbdd0; + + --sidebar-bg: #282d3f; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505274; + --sidebar-active: #2b79a2; + --sidebar-spacer: #2d334f; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #b7b9cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6; + + --theme-popup-bg: #161923; + --theme-popup-border: #737480; + --theme-hover: #282e40; + + --quote-bg: hsl(226, 15%, 17%); + --quote-border: hsl(226, 15%, 22%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(226, 23%, 16%); + --table-header-bg: hsl(226, 23%, 31%); + --table-alternate-bg: hsl(226, 23%, 14%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #aeaec6; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #5f5f71; + --searchresults-border-color: #5c5c68; + --searchresults-li-bg: #242430; + --search-mark-bg: #a2cff5; + + --color-scheme: dark; +} + +.rust { + --bg: hsl(60, 9%, 87%); + --fg: #262625; + + --sidebar-bg: #3b2e2a; + --sidebar-fg: #c8c9db; + --sidebar-non-existant: #505254; + --sidebar-active: #e69f67; + --sidebar-spacer: #45373a; + + --scrollbar: var(--sidebar-fg); + + --icons: #737480; + --icons-hover: #262625; + + --links: #2b79a2; + + --inline-code-color: #6e6b5e; + + --theme-popup-bg: #e1e1db; + --theme-popup-border: #b38f6b; + --theme-hover: #99908a; + + --quote-bg: hsl(60, 5%, 75%); + --quote-border: hsl(60, 5%, 70%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(60, 9%, 82%); + --table-header-bg: #b3a497; + --table-alternate-bg: hsl(60, 9%, 84%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #fafafa; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #888; + --searchresults-li-bg: #dec2a2; + --search-mark-bg: #e69f67; + + --color-scheme: light; +} + +@media (prefers-color-scheme: dark) { + .light.no-js { + --bg: hsl(200, 7%, 8%); + --fg: #98a3ad; + + --sidebar-bg: #292c2f; + --sidebar-fg: #a1adb8; + --sidebar-non-existant: #505254; + --sidebar-active: #3473ad; + --sidebar-spacer: #393939; + + --scrollbar: var(--sidebar-fg); + + --icons: #43484d; + --icons-hover: #b3c0cc; + + --links: #2b79a2; + + --inline-code-color: #c5c8c6; + + --theme-popup-bg: #141617; + --theme-popup-border: #43484d; + --theme-hover: #1f2124; + + --quote-bg: hsl(234, 21%, 18%); + --quote-border: hsl(234, 21%, 23%); + + --warning-border: #ff8e00; + + --table-border-color: hsl(200, 7%, 13%); + --table-header-bg: hsl(200, 7%, 28%); + --table-alternate-bg: hsl(200, 7%, 11%); + + --searchbar-border-color: #aaa; + --searchbar-bg: #b7b7b7; + --searchbar-fg: #000; + --searchbar-shadow-color: #aaa; + --searchresults-header-fg: #666; + --searchresults-border-color: #98a3ad; + --searchresults-li-bg: #2b2b2f; + --search-mark-bg: #355c7d; + } +} diff --git a/book/elasticlunr.min.js b/book/elasticlunr.min.js new file mode 100644 index 00000000..94b20dd2 --- /dev/null +++ b/book/elasticlunr.min.js @@ -0,0 +1,10 @@ +/** + * elasticlunr - http://weixsong.github.io + * Lightweight full-text search engine in Javascript for browser search and offline search. - 0.9.5 + * + * Copyright (C) 2017 Oliver Nightingale + * Copyright (C) 2017 Wei Song + * MIT Licensed + * @license + */ +!function(){function e(e){if(null===e||"object"!=typeof e)return e;var t=e.constructor();for(var n in e)e.hasOwnProperty(n)&&(t[n]=e[n]);return t}var t=function(e){var n=new t.Index;return n.pipeline.add(t.trimmer,t.stopWordFilter,t.stemmer),e&&e.call(n,n),n};t.version="0.9.5",lunr=t,t.utils={},t.utils.warn=function(e){return function(t){e.console&&console.warn&&console.warn(t)}}(this),t.utils.toString=function(e){return void 0===e||null===e?"":e.toString()},t.EventEmitter=function(){this.events={}},t.EventEmitter.prototype.addListener=function(){var e=Array.prototype.slice.call(arguments),t=e.pop(),n=e;if("function"!=typeof t)throw new TypeError("last argument must be a function");n.forEach(function(e){this.hasHandler(e)||(this.events[e]=[]),this.events[e].push(t)},this)},t.EventEmitter.prototype.removeListener=function(e,t){if(this.hasHandler(e)){var n=this.events[e].indexOf(t);-1!==n&&(this.events[e].splice(n,1),0==this.events[e].length&&delete this.events[e])}},t.EventEmitter.prototype.emit=function(e){if(this.hasHandler(e)){var t=Array.prototype.slice.call(arguments,1);this.events[e].forEach(function(e){e.apply(void 0,t)},this)}},t.EventEmitter.prototype.hasHandler=function(e){return e in this.events},t.tokenizer=function(e){if(!arguments.length||null===e||void 0===e)return[];if(Array.isArray(e)){var n=e.filter(function(e){return null===e||void 0===e?!1:!0});n=n.map(function(e){return t.utils.toString(e).toLowerCase()});var i=[];return n.forEach(function(e){var n=e.split(t.tokenizer.seperator);i=i.concat(n)},this),i}return e.toString().trim().toLowerCase().split(t.tokenizer.seperator)},t.tokenizer.defaultSeperator=/[\s\-]+/,t.tokenizer.seperator=t.tokenizer.defaultSeperator,t.tokenizer.setSeperator=function(e){null!==e&&void 0!==e&&"object"==typeof e&&(t.tokenizer.seperator=e)},t.tokenizer.resetSeperator=function(){t.tokenizer.seperator=t.tokenizer.defaultSeperator},t.tokenizer.getSeperator=function(){return t.tokenizer.seperator},t.Pipeline=function(){this._queue=[]},t.Pipeline.registeredFunctions={},t.Pipeline.registerFunction=function(e,n){n in t.Pipeline.registeredFunctions&&t.utils.warn("Overwriting existing registered function: "+n),e.label=n,t.Pipeline.registeredFunctions[n]=e},t.Pipeline.getRegisteredFunction=function(e){return e in t.Pipeline.registeredFunctions!=!0?null:t.Pipeline.registeredFunctions[e]},t.Pipeline.warnIfFunctionNotRegistered=function(e){var n=e.label&&e.label in this.registeredFunctions;n||t.utils.warn("Function is not registered with pipeline. This may cause problems when serialising the index.\n",e)},t.Pipeline.load=function(e){var n=new t.Pipeline;return e.forEach(function(e){var i=t.Pipeline.getRegisteredFunction(e);if(!i)throw new Error("Cannot load un-registered function: "+e);n.add(i)}),n},t.Pipeline.prototype.add=function(){var e=Array.prototype.slice.call(arguments);e.forEach(function(e){t.Pipeline.warnIfFunctionNotRegistered(e),this._queue.push(e)},this)},t.Pipeline.prototype.after=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i+1,0,n)},t.Pipeline.prototype.before=function(e,n){t.Pipeline.warnIfFunctionNotRegistered(n);var i=this._queue.indexOf(e);if(-1===i)throw new Error("Cannot find existingFn");this._queue.splice(i,0,n)},t.Pipeline.prototype.remove=function(e){var t=this._queue.indexOf(e);-1!==t&&this._queue.splice(t,1)},t.Pipeline.prototype.run=function(e){for(var t=[],n=e.length,i=this._queue.length,o=0;n>o;o++){for(var r=e[o],s=0;i>s&&(r=this._queue[s](r,o,e),void 0!==r&&null!==r);s++);void 0!==r&&null!==r&&t.push(r)}return t},t.Pipeline.prototype.reset=function(){this._queue=[]},t.Pipeline.prototype.get=function(){return this._queue},t.Pipeline.prototype.toJSON=function(){return this._queue.map(function(e){return t.Pipeline.warnIfFunctionNotRegistered(e),e.label})},t.Index=function(){this._fields=[],this._ref="id",this.pipeline=new t.Pipeline,this.documentStore=new t.DocumentStore,this.index={},this.eventEmitter=new t.EventEmitter,this._idfCache={},this.on("add","remove","update",function(){this._idfCache={}}.bind(this))},t.Index.prototype.on=function(){var e=Array.prototype.slice.call(arguments);return this.eventEmitter.addListener.apply(this.eventEmitter,e)},t.Index.prototype.off=function(e,t){return this.eventEmitter.removeListener(e,t)},t.Index.load=function(e){e.version!==t.version&&t.utils.warn("version mismatch: current "+t.version+" importing "+e.version);var n=new this;n._fields=e.fields,n._ref=e.ref,n.documentStore=t.DocumentStore.load(e.documentStore),n.pipeline=t.Pipeline.load(e.pipeline),n.index={};for(var i in e.index)n.index[i]=t.InvertedIndex.load(e.index[i]);return n},t.Index.prototype.addField=function(e){return this._fields.push(e),this.index[e]=new t.InvertedIndex,this},t.Index.prototype.setRef=function(e){return this._ref=e,this},t.Index.prototype.saveDocument=function(e){return this.documentStore=new t.DocumentStore(e),this},t.Index.prototype.addDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.addDoc(i,e),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));this.documentStore.addFieldLength(i,n,o.length);var r={};o.forEach(function(e){e in r?r[e]+=1:r[e]=1},this);for(var s in r){var u=r[s];u=Math.sqrt(u),this.index[n].addToken(s,{ref:i,tf:u})}},this),n&&this.eventEmitter.emit("add",e,this)}},t.Index.prototype.removeDocByRef=function(e){if(e&&this.documentStore.isDocStored()!==!1&&this.documentStore.hasDoc(e)){var t=this.documentStore.getDoc(e);this.removeDoc(t,!1)}},t.Index.prototype.removeDoc=function(e,n){if(e){var n=void 0===n?!0:n,i=e[this._ref];this.documentStore.hasDoc(i)&&(this.documentStore.removeDoc(i),this._fields.forEach(function(n){var o=this.pipeline.run(t.tokenizer(e[n]));o.forEach(function(e){this.index[n].removeToken(e,i)},this)},this),n&&this.eventEmitter.emit("remove",e,this))}},t.Index.prototype.updateDoc=function(e,t){var t=void 0===t?!0:t;this.removeDocByRef(e[this._ref],!1),this.addDoc(e,!1),t&&this.eventEmitter.emit("update",e,this)},t.Index.prototype.idf=function(e,t){var n="@"+t+"/"+e;if(Object.prototype.hasOwnProperty.call(this._idfCache,n))return this._idfCache[n];var i=this.index[t].getDocFreq(e),o=1+Math.log(this.documentStore.length/(i+1));return this._idfCache[n]=o,o},t.Index.prototype.getFields=function(){return this._fields.slice()},t.Index.prototype.search=function(e,n){if(!e)return[];e="string"==typeof e?{any:e}:JSON.parse(JSON.stringify(e));var i=null;null!=n&&(i=JSON.stringify(n));for(var o=new t.Configuration(i,this.getFields()).get(),r={},s=Object.keys(e),u=0;u0&&t.push(e);for(var i in n)"docs"!==i&&"df"!==i&&this.expandToken(e+i,t,n[i]);return t},t.InvertedIndex.prototype.toJSON=function(){return{root:this.root}},t.Configuration=function(e,n){var e=e||"";if(void 0==n||null==n)throw new Error("fields should not be null");this.config={};var i;try{i=JSON.parse(e),this.buildUserConfig(i,n)}catch(o){t.utils.warn("user configuration parse failed, will use default configuration"),this.buildDefaultConfig(n)}},t.Configuration.prototype.buildDefaultConfig=function(e){this.reset(),e.forEach(function(e){this.config[e]={boost:1,bool:"OR",expand:!1}},this)},t.Configuration.prototype.buildUserConfig=function(e,n){var i="OR",o=!1;if(this.reset(),"bool"in e&&(i=e.bool||i),"expand"in e&&(o=e.expand||o),"fields"in e)for(var r in e.fields)if(n.indexOf(r)>-1){var s=e.fields[r],u=o;void 0!=s.expand&&(u=s.expand),this.config[r]={boost:s.boost||0===s.boost?s.boost:1,bool:s.bool||i,expand:u}}else t.utils.warn("field name in user configuration not found in index instance fields");else this.addAllFields2UserConfig(i,o,n)},t.Configuration.prototype.addAllFields2UserConfig=function(e,t,n){n.forEach(function(n){this.config[n]={boost:1,bool:e,expand:t}},this)},t.Configuration.prototype.get=function(){return this.config},t.Configuration.prototype.reset=function(){this.config={}},lunr.SortedSet=function(){this.length=0,this.elements=[]},lunr.SortedSet.load=function(e){var t=new this;return t.elements=e,t.length=e.length,t},lunr.SortedSet.prototype.add=function(){var e,t;for(e=0;e1;){if(r===e)return o;e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o]}return r===e?o:-1},lunr.SortedSet.prototype.locationFor=function(e){for(var t=0,n=this.elements.length,i=n-t,o=t+Math.floor(i/2),r=this.elements[o];i>1;)e>r&&(t=o),r>e&&(n=o),i=n-t,o=t+Math.floor(i/2),r=this.elements[o];return r>e?o:e>r?o+1:void 0},lunr.SortedSet.prototype.intersect=function(e){for(var t=new lunr.SortedSet,n=0,i=0,o=this.length,r=e.length,s=this.elements,u=e.elements;;){if(n>o-1||i>r-1)break;s[n]!==u[i]?s[n]u[i]&&i++:(t.add(s[n]),n++,i++)}return t},lunr.SortedSet.prototype.clone=function(){var e=new lunr.SortedSet;return e.elements=this.toArray(),e.length=e.elements.length,e},lunr.SortedSet.prototype.union=function(e){var t,n,i;this.length>=e.length?(t=this,n=e):(t=e,n=this),i=t.clone();for(var o=0,r=n.toArray();o + + + + diff --git a/book/fonts/OPEN-SANS-LICENSE.txt b/book/fonts/OPEN-SANS-LICENSE.txt new file mode 100644 index 00000000..d6456956 --- /dev/null +++ b/book/fonts/OPEN-SANS-LICENSE.txt @@ -0,0 +1,202 @@ + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/book/fonts/SOURCE-CODE-PRO-LICENSE.txt b/book/fonts/SOURCE-CODE-PRO-LICENSE.txt new file mode 100644 index 00000000..366206f5 --- /dev/null +++ b/book/fonts/SOURCE-CODE-PRO-LICENSE.txt @@ -0,0 +1,93 @@ +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/book/fonts/fonts.css b/book/fonts/fonts.css new file mode 100644 index 00000000..858efa59 --- /dev/null +++ b/book/fonts/fonts.css @@ -0,0 +1,100 @@ +/* Open Sans is licensed under the Apache License, Version 2.0. See http://www.apache.org/licenses/LICENSE-2.0 */ +/* Source Code Pro is under the Open Font License. See https://scripts.sil.org/cms/scripts/page.php?site_id=nrsi&id=OFL */ + +/* open-sans-300 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 300; + src: local('Open Sans Light'), local('OpenSans-Light'), + url('open-sans-v17-all-charsets-300.woff2') format('woff2'); +} + +/* open-sans-300italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 300; + src: local('Open Sans Light Italic'), local('OpenSans-LightItalic'), + url('open-sans-v17-all-charsets-300italic.woff2') format('woff2'); +} + +/* open-sans-regular - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 400; + src: local('Open Sans Regular'), local('OpenSans-Regular'), + url('open-sans-v17-all-charsets-regular.woff2') format('woff2'); +} + +/* open-sans-italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 400; + src: local('Open Sans Italic'), local('OpenSans-Italic'), + url('open-sans-v17-all-charsets-italic.woff2') format('woff2'); +} + +/* open-sans-600 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 600; + src: local('Open Sans SemiBold'), local('OpenSans-SemiBold'), + url('open-sans-v17-all-charsets-600.woff2') format('woff2'); +} + +/* open-sans-600italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 600; + src: local('Open Sans SemiBold Italic'), local('OpenSans-SemiBoldItalic'), + url('open-sans-v17-all-charsets-600italic.woff2') format('woff2'); +} + +/* open-sans-700 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 700; + src: local('Open Sans Bold'), local('OpenSans-Bold'), + url('open-sans-v17-all-charsets-700.woff2') format('woff2'); +} + +/* open-sans-700italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 700; + src: local('Open Sans Bold Italic'), local('OpenSans-BoldItalic'), + url('open-sans-v17-all-charsets-700italic.woff2') format('woff2'); +} + +/* open-sans-800 - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: normal; + font-weight: 800; + src: local('Open Sans ExtraBold'), local('OpenSans-ExtraBold'), + url('open-sans-v17-all-charsets-800.woff2') format('woff2'); +} + +/* open-sans-800italic - latin_vietnamese_latin-ext_greek-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Open Sans'; + font-style: italic; + font-weight: 800; + src: local('Open Sans ExtraBold Italic'), local('OpenSans-ExtraBoldItalic'), + url('open-sans-v17-all-charsets-800italic.woff2') format('woff2'); +} + +/* source-code-pro-500 - latin_vietnamese_latin-ext_greek_cyrillic-ext_cyrillic */ +@font-face { + font-family: 'Source Code Pro'; + font-style: normal; + font-weight: 500; + src: url('source-code-pro-v11-all-charsets-500.woff2') format('woff2'); +} diff --git a/book/fonts/open-sans-v17-all-charsets-300.woff2 b/book/fonts/open-sans-v17-all-charsets-300.woff2 new file mode 100644 index 00000000..9f51be37 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-300.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-300italic.woff2 b/book/fonts/open-sans-v17-all-charsets-300italic.woff2 new file mode 100644 index 00000000..2f545448 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-300italic.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-600.woff2 b/book/fonts/open-sans-v17-all-charsets-600.woff2 new file mode 100644 index 00000000..f503d558 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-600.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-600italic.woff2 b/book/fonts/open-sans-v17-all-charsets-600italic.woff2 new file mode 100644 index 00000000..c99aabe8 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-600italic.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-700.woff2 b/book/fonts/open-sans-v17-all-charsets-700.woff2 new file mode 100644 index 00000000..421a1ab2 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-700.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-700italic.woff2 b/book/fonts/open-sans-v17-all-charsets-700italic.woff2 new file mode 100644 index 00000000..12ce3d20 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-700italic.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-800.woff2 b/book/fonts/open-sans-v17-all-charsets-800.woff2 new file mode 100644 index 00000000..c94a223b Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-800.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-800italic.woff2 b/book/fonts/open-sans-v17-all-charsets-800italic.woff2 new file mode 100644 index 00000000..eed7d3c6 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-800italic.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-italic.woff2 b/book/fonts/open-sans-v17-all-charsets-italic.woff2 new file mode 100644 index 00000000..398b68a0 Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-italic.woff2 differ diff --git a/book/fonts/open-sans-v17-all-charsets-regular.woff2 b/book/fonts/open-sans-v17-all-charsets-regular.woff2 new file mode 100644 index 00000000..8383e94c Binary files /dev/null and b/book/fonts/open-sans-v17-all-charsets-regular.woff2 differ diff --git a/book/fonts/source-code-pro-v11-all-charsets-500.woff2 b/book/fonts/source-code-pro-v11-all-charsets-500.woff2 new file mode 100644 index 00000000..72224568 Binary files /dev/null and b/book/fonts/source-code-pro-v11-all-charsets-500.woff2 differ diff --git a/book/highlight.css b/book/highlight.css new file mode 100644 index 00000000..ba57b82b --- /dev/null +++ b/book/highlight.css @@ -0,0 +1,82 @@ +/* + * An increased contrast highlighting scheme loosely based on the + * "Base16 Atelier Dune Light" theme by Bram de Haan + * (http://atelierbram.github.io/syntax-highlighting/atelier-schemes/dune) + * Original Base16 color scheme by Chris Kempson + * (https://github.com/chriskempson/base16) + */ + +/* Comment */ +.hljs-comment, +.hljs-quote { + color: #575757; +} + +/* Red */ +.hljs-variable, +.hljs-template-variable, +.hljs-attribute, +.hljs-tag, +.hljs-name, +.hljs-regexp, +.hljs-link, +.hljs-name, +.hljs-selector-id, +.hljs-selector-class { + color: #d70025; +} + +/* Orange */ +.hljs-number, +.hljs-meta, +.hljs-built_in, +.hljs-builtin-name, +.hljs-literal, +.hljs-type, +.hljs-params { + color: #b21e00; +} + +/* Green */ +.hljs-string, +.hljs-symbol, +.hljs-bullet { + color: #008200; +} + +/* Blue */ +.hljs-title, +.hljs-section { + color: #0030f2; +} + +/* Purple */ +.hljs-keyword, +.hljs-selector-tag { + color: #9d00ec; +} + +.hljs { + display: block; + overflow-x: auto; + background: #f6f7f6; + color: #000; +} + +.hljs-emphasis { + font-style: italic; +} + +.hljs-strong { + font-weight: bold; +} + +.hljs-addition { + color: #22863a; + background-color: #f0fff4; +} + +.hljs-deletion { + color: #b31d28; + background-color: #ffeef0; +} diff --git a/book/highlight.js b/book/highlight.js new file mode 100644 index 00000000..18d24345 --- /dev/null +++ b/book/highlight.js @@ -0,0 +1,54 @@ +/* + Highlight.js 10.1.1 (93fd0d73) + License: BSD-3-Clause + Copyright (c) 2006-2020, Ivan Sagalaev +*/ +var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s="",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset"}function u(e){s+=""}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var g=l();if(s+=t(r.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+t(r.substr(i))}});const s="",o=e=>!!e.kind;class l{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=``}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h={begin:"\\\\[\\s\\S]",relevance:0},f={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[h]},p={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[h]},b={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,t={}){var a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(b),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},v=m("//","$"),x=m("/\\*","\\*/"),E=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:g,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>d(e)).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:b,COMMENT:m,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:g,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[h,{begin:/\[/,end:/\]/,relevance:0,contains:[h]}]}]},TITLE_MODE:{className:"title",begin:"[a-zA-Z]\\w*",relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}}),N="of and for in not or if then".split(" ");function w(e,n){return n?+n:function(e){return N.includes(e.toLowerCase())}(e)?0:1}const R=t,y=r,{nodeStream:k,mergeStreams:O}=i,M=Symbol("nomatch");return function(t){var a=[],i={},s={},o=[],l=!0,c=/(^(<[^>]+>|\t|)+|\n)/gm,g="Could not find the language '{}', did you forget to load/include a language module?";const h={disableAutodetect:!0,name:"Plain text",contains:[]};var f={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:u};function p(e){return f.noHighlightRe.test(e)}function b(e,n,t,r){var a={code:n,language:e};S("before:highlight",a);var i=a.result?a.result:m(a.language,a.code,t,r);return i.code=a.code,S("after:highlight",i),i}function m(e,t,a,s){var o=t;function c(e,n){var t=E.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function u(){null!=y.subLanguage?function(){if(""!==A){var e=null;if("string"==typeof y.subLanguage){if(!i[y.subLanguage])return void O.addText(A);e=m(y.subLanguage,A,!0,k[y.subLanguage]),k[y.subLanguage]=e.top}else e=v(A,y.subLanguage.length?y.subLanguage:null);y.relevance>0&&(I+=e.relevance),O.addSublanguage(e.emitter,e.language)}}():function(){if(!y.keywords)return void O.addText(A);let e=0;y.keywordPatternRe.lastIndex=0;let n=y.keywordPatternRe.exec(A),t="";for(;n;){t+=A.substring(e,n.index);const r=c(y,n);if(r){const[e,a]=r;O.addText(t),t="",I+=a,O.addKeyword(n[0],e)}else t+=n[0];e=y.keywordPatternRe.lastIndex,n=y.keywordPatternRe.exec(A)}t+=A.substr(e),O.addText(t)}(),A=""}function h(e){return e.className&&O.openNode(e.className),y=Object.create(e,{parent:{value:y}})}function p(e){return 0===y.matcher.regexIndex?(A+=e[0],1):(L=!0,0)}var b={};function x(t,r){var i=r&&r[0];if(A+=t,null==i)return u(),0;if("begin"===b.type&&"end"===r.type&&b.index===r.index&&""===i){if(A+=o.slice(r.index,r.index+1),!l){const n=Error("0 width match regex");throw n.languageName=e,n.badRule=b.rule,n}return 1}if(b=r,"begin"===r.type)return function(e){var t=e[0],r=e.rule;const a=new n(r),i=[r.__beforeBegin,r["on:begin"]];for(const n of i)if(n&&(n(e,a),a.ignore))return p(t);return r&&r.endSameAsBegin&&(r.endRe=RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),r.skip?A+=t:(r.excludeBegin&&(A+=t),u(),r.returnBegin||r.excludeBegin||(A=t)),h(r),r.returnBegin?0:t.length}(r);if("illegal"===r.type&&!a){const e=Error('Illegal lexeme "'+i+'" for mode "'+(y.className||"")+'"');throw e.mode=y,e}if("end"===r.type){var s=function(e){var t=e[0],r=o.substr(e.index),a=function e(t,r,a){let i=function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(t.endRe,a);if(i){if(t["on:end"]){const e=new n(t);t["on:end"](r,e),e.ignore&&(i=!1)}if(i){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,r,a)}(y,e,r);if(!a)return M;var i=y;i.skip?A+=t:(i.returnEnd||i.excludeEnd||(A+=t),u(),i.excludeEnd&&(A=t));do{y.className&&O.closeNode(),y.skip||y.subLanguage||(I+=y.relevance),y=y.parent}while(y!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}(r);if(s!==M)return s}if("illegal"===r.type&&""===i)return 1;if(B>1e5&&B>3*r.index)throw Error("potential infinite loop, way more iterations than matches");return A+=i,i.length}var E=T(e);if(!E)throw console.error(g.replace("{}",e)),Error('Unknown language: "'+e+'"');var _=function(e){function n(n,t){return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n="|"){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i0&&(a+=n),a+="(";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),"\\"===l[0][0]&&l[1]?a+="\\"+(+l[1]+s):(a+=l[0],"("===l[0]&&r++)}a+=")"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex((e,n)=>n>0&&void 0!==e),r=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;const t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e,n){const t=e.input[e.index-1],r=e.input[e.index+e[0].length];"."!==t&&"."!==r||n.ignoreMatch()}if(e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language. See documentation.");return function t(s,o){const l=s;if(s.compiled)return l;s.compiled=!0,s.__beforeBegin=null,s.keywords=s.keywords||s.beginKeywords;let c=null;if("object"==typeof s.keywords&&(c=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=function(e,n){var t={};return"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(" ").forEach((function(n){var r=n.split("|");t[r[0]]=[e,w(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemes&&c)throw Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l.keywordPatternRe=n(s.lexemes||c||/\w+/,!0),o&&(s.beginKeywords&&(s.begin="\\b("+s.beginKeywords.split(" ").join("|")+")(?=\\b|\\s)",s.__beforeBegin=i),s.begin||(s.begin=/\B|\b/),l.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),s.end&&(l.endRe=n(s.end)),l.terminator_end=d(s.end)||"",s.endsWithParent&&o.terminator_end&&(l.terminator_end+=(s.end?"|":"")+o.terminator_end)),s.illegal&&(l.illegalRe=n(s.illegal)),void 0===s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return r(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?r(e,{starts:e.starts?r(e.starts):null}):Object.isFrozen(e)?r(e):e}("self"===e?s:e)}))),s.contains.forEach((function(e){t(e,l)})),s.starts&&t(s.starts,o),l.matcher=function(e){const n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminator_end&&n.addRule(e.terminator_end,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(l),l}(e)}(E),N="",y=s||_,k={},O=new f.__emitter(f);!function(){for(var e=[],n=y;n!==E;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>O.openNode(e))}();var A="",I=0,S=0,B=0,L=!1;try{for(y.matcher.considerAll();;){B++,L?L=!1:(y.matcher.lastIndex=S,y.matcher.considerAll());const e=y.matcher.exec(o);if(!e)break;const n=x(o.substring(S,e.index),e);S=e.index+n}return x(o.substr(S)),O.closeAllNodes(),O.finalize(),N=O.toHTML(),{relevance:I,value:N,language:e,illegal:!1,emitter:O,top:y}}catch(n){if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:n.message,context:o.slice(S-100,S+100),mode:n.mode},sofar:N,relevance:0,value:R(o),emitter:O};if(l)return{illegal:!1,relevance:0,value:R(o),emitter:O,language:e,top:y,errorRaised:n};throw n}}function v(e,n){n=n||f.languages||Object.keys(i);var t=function(e){const n={relevance:0,emitter:new f.__emitter(f),value:R(e),illegal:!1,top:h};return n.emitter.addText(e),n}(e),r=t;return n.filter(T).filter(I).forEach((function(n){var a=m(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function x(e){return f.tabReplace||f.useBR?e.replace(c,e=>"\n"===e?f.useBR?"
":e:f.tabReplace?e.replace(/\t/g,f.tabReplace):e):e}function E(e){let n=null;const t=function(e){var n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=f.languageDetectRe.exec(n);if(t){var r=T(t[1]);return r||(console.warn(g.replace("{}",t[1])),console.warn("Falling back to no-highlight mode for this block.",e)),r?t[1]:"no-highlight"}return n.split(/\s+/).find(e=>p(e)||T(e))}(e);if(p(t))return;S("before:highlightBlock",{block:e,language:t}),f.useBR?(n=document.createElement("div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(//g,"\n"):n=e;const r=n.textContent,a=t?b(t,r,!0):v(r),i=k(n);if(i.length){const e=document.createElement("div");e.innerHTML=a.value,a.value=O(i,k(e),r)}a.value=x(a.value),S("after:highlightBlock",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,n,t){var r=n?s[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,t,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const N=()=>{if(!N.called){N.called=!0;var e=document.querySelectorAll("pre code");a.forEach.call(e,E)}};function T(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]}function A(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach(e=>{s[e]=n})}function I(e){var n=T(e);return n&&!n.disableAutodetect}function S(e,n){var t=e;o.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(t,{highlight:b,highlightAuto:v,fixMarkup:x,highlightBlock:E,configure:function(e){f=y(f,e)},initHighlighting:N,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",N,!1)},registerLanguage:function(e,n){var r=null;try{r=n(t)}catch(n){if(console.error("Language definition for '{}' could not be registered.".replace("{}",e)),!l)throw n;console.error(n),r=h}r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&A(r.aliases,{languageName:e})},listLanguages:function(){return Object.keys(i)},getLanguage:T,registerAliases:A,requireLanguage:function(e){var n=T(e);if(n)return n;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:I,inherit:y,addPlugin:function(e){o.push(e)}}),t.debugMode=function(){l=!1},t.safeMode=function(){l=!0},t.versionString="10.1.1";for(const n in _)"object"==typeof _[n]&&e(_[n]);return Object.assign(t,_),t}({})}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs); +hljs.registerLanguage("apache",function(){"use strict";return function(e){var n={className:"number",begin:"\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?"};return{name:"Apache config",aliases:["apacheconf"],case_insensitive:!0,contains:[e.HASH_COMMENT_MODE,{className:"section",begin:"",contains:[n,{className:"number",begin:":\\d{1,5}"},e.inherit(e.QUOTE_STRING_MODE,{relevance:0})]},{className:"attribute",begin:/\w+/,relevance:0,keywords:{nomarkup:"order deny allow setenv rewriterule rewriteengine rewritecond documentroot sethandler errordocument loadmodule options header listen serverroot servername"},starts:{end:/$/,relevance:0,keywords:{literal:"on off all deny allow"},contains:[{className:"meta",begin:"\\s\\[",end:"\\]$"},{className:"variable",begin:"[\\$%]\\{",end:"\\}",contains:["self",{className:"number",begin:"[\\$%]\\d+"}]},n,{className:"number",begin:"\\d+"},e.QUOTE_STRING_MODE]}}],illegal:/\S/}}}()); +hljs.registerLanguage("bash",function(){"use strict";return function(e){const s={};Object.assign(s,{className:"variable",variants:[{begin:/\$[\w\d#@][\w\d_]*/},{begin:/\$\{/,end:/\}/,contains:[{begin:/:-/,contains:[s]}]}]});const t={className:"subst",begin:/\$\(/,end:/\)/,contains:[e.BACKSLASH_ESCAPE]},n={className:"string",begin:/"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,t]};t.contains.push(n);const a={begin:/\$\(\(/,end:/\)\)/,contains:[{begin:/\d+#[0-9a-f]+/,className:"number"},e.NUMBER_MODE,s]},i=e.SHEBANG({binary:"(fish|bash|zsh|sh|csh|ksh|tcsh|dash|scsh)",relevance:10}),c={className:"function",begin:/\w[\w\d_]*\s*\(\s*\)\s*\{/,returnBegin:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/\w[\w\d_]*/})],relevance:0};return{name:"Bash",aliases:["sh","zsh"],keywords:{$pattern:/\b-?[a-z\._]+\b/,keyword:"if then else elif fi for while in do done case esac function",literal:"true false",built_in:"break cd continue eval exec exit export getopts hash pwd readonly return shift test times trap umask unset alias bind builtin caller command declare echo enable help let local logout mapfile printf read readarray source type typeset ulimit unalias set shopt autoload bg bindkey bye cap chdir clone comparguments compcall compctl compdescribe compfiles compgroups compquote comptags comptry compvalues dirs disable disown echotc echoti emulate fc fg float functions getcap getln history integer jobs kill limit log noglob popd print pushd pushln rehash sched setcap setopt stat suspend ttyctl unfunction unhash unlimit unsetopt vared wait whence where which zcompile zformat zftp zle zmodload zparseopts zprof zpty zregexparse zsocket zstyle ztcp",_:"-ne -eq -lt -gt -f -d -e -s -l -a"},contains:[i,e.SHEBANG(),c,a,e.HASH_COMMENT_MODE,n,{className:"",begin:/\\"/},{className:"string",begin:/'/,end:/'/},s]}}}()); +hljs.registerLanguage("c-like",function(){"use strict";return function(e){function t(e){return"(?:"+e+")?"}var n="(decltype\\(auto\\)|"+t("[a-zA-Z_]\\w*::")+"[a-zA-Z_]\\w*"+t("<.*?>")+")",r={className:"keyword",begin:"\\b[a-z\\d_]*_t\\b"},a={className:"string",variants:[{begin:'(u8?|U|L)?"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:"(u8?|U|L)?'(\\\\(x[0-9A-Fa-f]{2}|u[0-9A-Fa-f]{4,8}|[0-7]{3}|\\S)|.)",end:"'",illegal:"."},e.END_SAME_AS_BEGIN({begin:/(?:u8?|U|L)?R"([^()\\ ]{0,16})\(/,end:/\)([^()\\ ]{0,16})"/})]},i={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"meta",begin:/#\s*[a-z]+\b/,end:/$/,keywords:{"meta-keyword":"if else elif endif define undef warning error line pragma _Pragma ifdef ifndef include"},contains:[{begin:/\\\n/,relevance:0},e.inherit(a,{className:"meta-string"}),{className:"meta-string",begin:/<.*?>/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},o={className:"title",begin:t("[a-zA-Z_]\\w*::")+e.IDENT_RE,relevance:0},c=t("[a-zA-Z_]\\w*::")+e.IDENT_RE+"\\s*\\(",l={keyword:"int float while private char char8_t char16_t char32_t catch import module export virtual operator sizeof dynamic_cast|10 typedef const_cast|10 const for static_cast|10 union namespace unsigned long volatile static protected bool template mutable if public friend do goto auto void enum else break extern using asm case typeid wchar_t short reinterpret_cast|10 default double register explicit signed typename try this switch continue inline delete alignas alignof constexpr consteval constinit decltype concept co_await co_return co_yield requires noexcept static_assert thread_local restrict final override atomic_bool atomic_char atomic_schar atomic_uchar atomic_short atomic_ushort atomic_int atomic_uint atomic_long atomic_ulong atomic_llong atomic_ullong new throw return and and_eq bitand bitor compl not not_eq or or_eq xor xor_eq",built_in:"std string wstring cin cout cerr clog stdin stdout stderr stringstream istringstream ostringstream auto_ptr deque list queue stack vector map set pair bitset multiset multimap unordered_set unordered_map unordered_multiset unordered_multimap priority_queue make_pair array shared_ptr abort terminate abs acos asin atan2 atan calloc ceil cosh cos exit exp fabs floor fmod fprintf fputs free frexp fscanf future isalnum isalpha iscntrl isdigit isgraph islower isprint ispunct isspace isupper isxdigit tolower toupper labs ldexp log10 log malloc realloc memchr memcmp memcpy memset modf pow printf putchar puts scanf sinh sin snprintf sprintf sqrt sscanf strcat strchr strcmp strcpy strcspn strlen strncat strncmp strncpy strpbrk strrchr strspn strstr tanh tan vfprintf vprintf vsprintf endl initializer_list unique_ptr _Bool complex _Complex imaginary _Imaginary",literal:"true false nullptr NULL"},d=[r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,i,a],_={variants:[{begin:/=/,end:/;/},{begin:/\(/,end:/\)/},{beginKeywords:"new throw return else",end:/;/}],keywords:l,contains:d.concat([{begin:/\(/,end:/\)/,keywords:l,contains:d.concat(["self"]),relevance:0}]),relevance:0},u={className:"function",begin:"("+n+"[\\*&\\s]+)+"+c,returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:l,illegal:/[^\w\s\*&:<>]/,contains:[{begin:"decltype\\(auto\\)",keywords:l,relevance:0},{begin:c,returnBegin:!0,contains:[o],relevance:0},{className:"params",begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r,{begin:/\(/,end:/\)/,keywords:l,relevance:0,contains:["self",e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,i,r]}]},r,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s]};return{aliases:["c","cc","h","c++","h++","hpp","hh","hxx","cxx"],keywords:l,disableAutodetect:!0,illegal:"",keywords:l,contains:["self",r]},{begin:e.IDENT_RE+"::",keywords:l},{className:"class",beginKeywords:"class struct",end:/[{;:]/,contains:[{begin://,contains:["self"]},e.TITLE_MODE]}]),exports:{preprocessor:s,strings:a,keywords:l}}}}()); +hljs.registerLanguage("c",function(){"use strict";return function(e){var n=e.getLanguage("c-like").rawDefinition();return n.name="C",n.aliases=["c","h"],n}}()); +hljs.registerLanguage("coffeescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={keyword:e.concat(["then","unless","until","loop","by","when","and","or","is","isnt","not"]).filter((e=>n=>!e.includes(n))(["var","const","let","function","static"])).join(" "),literal:n.concat(["yes","no","on","off"]).join(" "),built_in:a.concat(["npm","print"]).join(" ")},i="[A-Za-z$_][0-9A-Za-z$_]*",s={className:"subst",begin:/#\{/,end:/}/,keywords:t},o=[r.BINARY_NUMBER_MODE,r.inherit(r.C_NUMBER_MODE,{starts:{end:"(\\s*/)?",relevance:0}}),{className:"string",variants:[{begin:/'''/,end:/'''/,contains:[r.BACKSLASH_ESCAPE]},{begin:/'/,end:/'/,contains:[r.BACKSLASH_ESCAPE]},{begin:/"""/,end:/"""/,contains:[r.BACKSLASH_ESCAPE,s]},{begin:/"/,end:/"/,contains:[r.BACKSLASH_ESCAPE,s]}]},{className:"regexp",variants:[{begin:"///",end:"///",contains:[s,r.HASH_COMMENT_MODE]},{begin:"//[gim]{0,3}(?=\\W)",relevance:0},{begin:/\/(?![ *]).*?(?![\\]).\/[gim]{0,3}(?=\W)/}]},{begin:"@"+i},{subLanguage:"javascript",excludeBegin:!0,excludeEnd:!0,variants:[{begin:"```",end:"```"},{begin:"`",end:"`"}]}];s.contains=o;var c=r.inherit(r.TITLE_MODE,{begin:i}),l={className:"params",begin:"\\([^\\(]",returnBegin:!0,contains:[{begin:/\(/,end:/\)/,keywords:t,contains:["self"].concat(o)}]};return{name:"CoffeeScript",aliases:["coffee","cson","iced"],keywords:t,illegal:/\/\*/,contains:o.concat([r.COMMENT("###","###"),r.HASH_COMMENT_MODE,{className:"function",begin:"^\\s*"+i+"\\s*=\\s*(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[c,l]},{begin:/[:\(,=]\s*/,relevance:0,contains:[{className:"function",begin:"(\\(.*\\))?\\s*\\B[-=]>",end:"[-=]>",returnBegin:!0,contains:[l]}]},{className:"class",beginKeywords:"class",end:"$",illegal:/[:="\[\]]/,contains:[{beginKeywords:"extends",endsWithParent:!0,illegal:/[:="\[\]]/,contains:[c]},c]},{begin:i+":",end:":",returnBegin:!0,returnEnd:!0,relevance:0}])}}}()); +hljs.registerLanguage("cpp",function(){"use strict";return function(e){var t=e.getLanguage("c-like").rawDefinition();return t.disableAutodetect=!1,t.name="C++",t.aliases=["cc","c++","h++","hpp","hh","hxx","cxx"],t}}()); +hljs.registerLanguage("csharp",function(){"use strict";return function(e){var n={keyword:"abstract as base bool break byte case catch char checked const continue decimal default delegate do double enum event explicit extern finally fixed float for foreach goto if implicit in int interface internal is lock long object operator out override params private protected public readonly ref sbyte sealed short sizeof stackalloc static string struct switch this try typeof uint ulong unchecked unsafe ushort using virtual void volatile while add alias ascending async await by descending dynamic equals from get global group into join let nameof on orderby partial remove select set value var when where yield",literal:"null false true"},i=e.inherit(e.TITLE_MODE,{begin:"[a-zA-Z](\\.?\\w)*"}),a={className:"number",variants:[{begin:"\\b(0b[01']+)"},{begin:"(-?)\\b([\\d']+(\\.[\\d']*)?|\\.[\\d']+)(u|U|l|L|ul|UL|f|F|b|B)"},{begin:"(-?)(\\b0[xX][a-fA-F0-9']+|(\\b[\\d']+(\\.[\\d']*)?|\\.[\\d']+)([eE][-+]?[\\d']+)?)"}],relevance:0},s={className:"string",begin:'@"',end:'"',contains:[{begin:'""'}]},t=e.inherit(s,{illegal:/\n/}),l={className:"subst",begin:"{",end:"}",keywords:n},r=e.inherit(l,{illegal:/\n/}),c={className:"string",begin:/\$"/,end:'"',illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},e.BACKSLASH_ESCAPE,r]},o={className:"string",begin:/\$@"/,end:'"',contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},l]},g=e.inherit(o,{illegal:/\n/,contains:[{begin:"{{"},{begin:"}}"},{begin:'""'},r]});l.contains=[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.C_BLOCK_COMMENT_MODE],r.contains=[g,c,t,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,a,e.inherit(e.C_BLOCK_COMMENT_MODE,{illegal:/\n/})];var d={variants:[o,c,s,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},E={begin:"<",end:">",contains:[{beginKeywords:"in out"},i]},_=e.IDENT_RE+"(<"+e.IDENT_RE+"(\\s*,\\s*"+e.IDENT_RE+")*>)?(\\[\\])?",b={begin:"@"+e.IDENT_RE,relevance:0};return{name:"C#",aliases:["cs","c#"],keywords:n,illegal:/::/,contains:[e.COMMENT("///","$",{returnBegin:!0,contains:[{className:"doctag",variants:[{begin:"///",relevance:0},{begin:"\x3c!--|--\x3e"},{begin:""}]}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"meta",begin:"#",end:"$",keywords:{"meta-keyword":"if else elif endif define undef warning error line region endregion pragma checksum"}},d,a,{beginKeywords:"class interface",end:/[{;=]/,illegal:/[^\s:,]/,contains:[{beginKeywords:"where class"},i,E,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{beginKeywords:"namespace",end:/[{;=]/,illegal:/[^\s:]/,contains:[i,e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"meta",begin:"^\\s*\\[",excludeBegin:!0,end:"\\]",excludeEnd:!0,contains:[{className:"meta-string",begin:/"/,end:/"/}]},{beginKeywords:"new return throw await else",relevance:0},{className:"function",begin:"("+_+"\\s+)+"+e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,end:/\s*[{;=]/,excludeEnd:!0,keywords:n,contains:[{begin:e.IDENT_RE+"\\s*(\\<.+\\>)?\\s*\\(",returnBegin:!0,contains:[e.TITLE_MODE,E],relevance:0},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:n,relevance:0,contains:[d,a,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},b]}}}()); +hljs.registerLanguage("css",function(){"use strict";return function(e){var n={begin:/(?:[A-Z\_\.\-]+|--[a-zA-Z0-9_-]+)\s*:/,returnBegin:!0,end:";",endsWithParent:!0,contains:[{className:"attribute",begin:/\S/,end:":",excludeEnd:!0,starts:{endsWithParent:!0,excludeEnd:!0,contains:[{begin:/[\w-]+\(/,returnBegin:!0,contains:[{className:"built_in",begin:/[\w-]+/},{begin:/\(/,end:/\)/,contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{className:"number",begin:"#[0-9A-Fa-f]+"},{className:"meta",begin:"!important"}]}}]};return{name:"CSS",case_insensitive:!0,illegal:/[=\/|'\$]/,contains:[e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:/#[A-Za-z0-9_-]+/},{className:"selector-class",begin:/\.[A-Za-z0-9_-]+/},{className:"selector-attr",begin:/\[/,end:/\]/,illegal:"$",contains:[e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",illegal:/:/,returnBegin:!0,contains:[{className:"keyword",begin:/@\-?\w[\w]*(\-\w+)*/},{begin:/\s/,endsWithParent:!0,excludeEnd:!0,relevance:0,keywords:"and or not only",contains:[{begin:/[a-z-]+:/,className:"attribute"},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.CSS_NUMBER_MODE]}]},{className:"selector-tag",begin:"[a-zA-Z-][a-zA-Z0-9_-]*",relevance:0},{begin:"{",end:"}",illegal:/\S/,contains:[e.C_BLOCK_COMMENT_MODE,n]}]}}}()); +hljs.registerLanguage("diff",function(){"use strict";return function(e){return{name:"Diff",aliases:["patch"],contains:[{className:"meta",relevance:10,variants:[{begin:/^@@ +\-\d+,\d+ +\+\d+,\d+ +@@$/},{begin:/^\*\*\* +\d+,\d+ +\*\*\*\*$/},{begin:/^\-\-\- +\d+,\d+ +\-\-\-\-$/}]},{className:"comment",variants:[{begin:/Index: /,end:/$/},{begin:/={3,}/,end:/$/},{begin:/^\-{3}/,end:/$/},{begin:/^\*{3} /,end:/$/},{begin:/^\+{3}/,end:/$/},{begin:/^\*{15}$/}]},{className:"addition",begin:"^\\+",end:"$"},{className:"deletion",begin:"^\\-",end:"$"},{className:"addition",begin:"^\\!",end:"$"}]}}}()); +hljs.registerLanguage("go",function(){"use strict";return function(e){var n={keyword:"break default func interface select case map struct chan else goto package switch const fallthrough if range type continue for import return var go defer bool byte complex64 complex128 float32 float64 int8 int16 int32 int64 string uint8 uint16 uint32 uint64 int uint uintptr rune",literal:"true false iota nil",built_in:"append cap close complex copy imag len make new panic print println real recover delete"};return{name:"Go",aliases:["golang"],keywords:n,illegal:"e(n)).join("")}return function(a){var s={className:"number",relevance:0,variants:[{begin:/([\+\-]+)?[\d]+_[\d_]+/},{begin:a.NUMBER_RE}]},i=a.COMMENT();i.variants=[{begin:/;/,end:/$/},{begin:/#/,end:/$/}];var t={className:"variable",variants:[{begin:/\$[\w\d"][\w\d_]*/},{begin:/\$\{(.*?)}/}]},r={className:"literal",begin:/\bon|off|true|false|yes|no\b/},l={className:"string",contains:[a.BACKSLASH_ESCAPE],variants:[{begin:"'''",end:"'''",relevance:10},{begin:'"""',end:'"""',relevance:10},{begin:'"',end:'"'},{begin:"'",end:"'"}]},c={begin:/\[/,end:/\]/,contains:[i,r,t,l,s,"self"],relevance:0},g="("+[/[A-Za-z0-9_-]+/,/"(\\"|[^"])*"/,/'[^']*'/].map(n=>e(n)).join("|")+")";return{name:"TOML, also INI",aliases:["toml"],case_insensitive:!0,illegal:/\S/,contains:[i,{className:"section",begin:/\[+/,end:/\]+/},{begin:n(g,"(\\s*\\.\\s*",g,")*",n("(?=",/\s*=\s*[^#\s]/,")")),className:"attr",starts:{end:/$/,contains:[i,c,r,t,l,s]}}]}}}()); +hljs.registerLanguage("java",function(){"use strict";function e(e){return e?"string"==typeof e?e:e.source:null}function n(e){return a("(",e,")?")}function a(...n){return n.map(n=>e(n)).join("")}function s(...n){return"("+n.map(n=>e(n)).join("|")+")"}return function(e){var t="false synchronized int abstract float private char boolean var static null if const for true while long strictfp finally protected import native final void enum else break transient catch instanceof byte super volatile case assert short package default double public try this switch continue throws protected public private module requires exports do",i={className:"meta",begin:"@[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*",contains:[{begin:/\(/,end:/\)/,contains:["self"]}]},r=e=>a("[",e,"]+([",e,"_]*[",e,"]+)?"),c={className:"number",variants:[{begin:`\\b(0[bB]${r("01")})[lL]?`},{begin:`\\b(0${r("0-7")})[dDfFlL]?`},{begin:a(/\b0[xX]/,s(a(r("a-fA-F0-9"),/\./,r("a-fA-F0-9")),a(r("a-fA-F0-9"),/\.?/),a(/\./,r("a-fA-F0-9"))),/([pP][+-]?(\d+))?/,/[fFdDlL]?/)},{begin:a(/\b/,s(a(/\d*\./,r("\\d")),r("\\d")),/[eE][+-]?[\d]+[dDfF]?/)},{begin:a(/\b/,r(/\d/),n(/\.?/),n(r(/\d/)),/[dDfFlL]?/)}],relevance:0};return{name:"Java",aliases:["jsp"],keywords:t,illegal:/<\/|#/,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{begin:/\w+@/,relevance:0},{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"class",beginKeywords:"class interface",end:/[{;=]/,excludeEnd:!0,keywords:"class interface",illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"new throw return else",relevance:0},{className:"function",begin:"([À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(<[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*(\\s*,\\s*[À-ʸa-zA-Z_$][À-ʸa-zA-Z_$0-9]*)*>)?\\s+)+"+e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,end:/[{;=]/,excludeEnd:!0,keywords:t,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"params",begin:/\(/,end:/\)/,keywords:t,relevance:0,contains:[i,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE]},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},c,i]}}}()); +hljs.registerLanguage("javascript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);function s(e){return r("(?=",e,")")}function r(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(t){var i="[A-Za-z$_][0-9A-Za-z$_]*",c={begin:/<[A-Za-z0-9\\._:-]+/,end:/\/[A-Za-z0-9\\._:-]+>|\/>/},o={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.join(" "),literal:n.join(" "),built_in:a.join(" ")},l={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:t.C_NUMBER_RE+"n?"}],relevance:0},E={className:"subst",begin:"\\$\\{",end:"\\}",keywords:o,contains:[]},d={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"xml"}},g={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[t.BACKSLASH_ESCAPE,E],subLanguage:"css"}},u={className:"string",begin:"`",end:"`",contains:[t.BACKSLASH_ESCAPE,E]};E.contains=[t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,l,t.REGEXP_MODE];var b=E.contains.concat([{begin:/\(/,end:/\)/,contains:["self"].concat(E.contains,[t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE])},t.C_BLOCK_COMMENT_MODE,t.C_LINE_COMMENT_MODE]),_={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:b};return{name:"JavaScript",aliases:["js","jsx","mjs","cjs"],keywords:o,contains:[t.SHEBANG({binary:"node",relevance:5}),{className:"meta",relevance:10,begin:/^\s*['"]use (strict|asm)['"]/},t.APOS_STRING_MODE,t.QUOTE_STRING_MODE,d,g,u,t.C_LINE_COMMENT_MODE,t.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+",contains:[{className:"type",begin:"\\{",end:"\\}",relevance:0},{className:"variable",begin:i+"(?=\\s*(-)|$)",endsParent:!0,relevance:0},{begin:/(?=[^\n])\s/,relevance:0}]}]}),t.C_BLOCK_COMMENT_MODE,l,{begin:r(/[{,\n]\s*/,s(r(/(((\/\/.*)|(\/\*(.|\n)*\*\/))\s*)*/,i+"\\s*:"))),relevance:0,contains:[{className:"attr",begin:i+s("\\s*:"),relevance:0}]},{begin:"("+t.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[t.C_LINE_COMMENT_MODE,t.C_BLOCK_COMMENT_MODE,t.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+t.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:t.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:o,contains:b}]}]},{begin:/,/,relevance:0},{className:"",begin:/\s/,end:/\s*/,skip:!0},{variants:[{begin:"<>",end:""},{begin:c.begin,end:c.end}],subLanguage:"xml",contains:[{begin:c.begin,end:c.end,skip:!0,contains:["self"]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/\{/,excludeEnd:!0,contains:[t.inherit(t.TITLE_MODE,{begin:i}),_],illegal:/\[|%/},{begin:/\$[(.]/},t.METHOD_GUARD,{className:"class",beginKeywords:"class",end:/[{;=]/,excludeEnd:!0,illegal:/[:"\[\]]/,contains:[{beginKeywords:"extends"},t.UNDERSCORE_TITLE_MODE]},{beginKeywords:"constructor",end:/\{/,excludeEnd:!0},{begin:"(get|set)\\s+(?="+i+"\\()",end:/{/,keywords:"get set",contains:[t.inherit(t.TITLE_MODE,{begin:i}),{begin:/\(\)/},_]}],illegal:/#(?!!)/}}}()); +hljs.registerLanguage("json",function(){"use strict";return function(n){var e={literal:"true false null"},i=[n.C_LINE_COMMENT_MODE,n.C_BLOCK_COMMENT_MODE],t=[n.QUOTE_STRING_MODE,n.C_NUMBER_MODE],a={end:",",endsWithParent:!0,excludeEnd:!0,contains:t,keywords:e},l={begin:"{",end:"}",contains:[{className:"attr",begin:/"/,end:/"/,contains:[n.BACKSLASH_ESCAPE],illegal:"\\n"},n.inherit(a,{begin:/:/})].concat(i),illegal:"\\S"},s={begin:"\\[",end:"\\]",contains:[n.inherit(a)],illegal:"\\S"};return t.push(l,s),i.forEach((function(n){t.push(n)})),{name:"JSON",contains:t,keywords:e,illegal:"\\S"}}}()); +hljs.registerLanguage("kotlin",function(){"use strict";return function(e){var n={keyword:"abstract as val var vararg get set class object open private protected public noinline crossinline dynamic final enum if else do while for when throw try catch finally import package is in fun override companion reified inline lateinit init interface annotation data sealed internal infix operator out by constructor super tailrec where const inner suspend typealias external expect actual trait volatile transient native default",built_in:"Byte Short Char Int Long Boolean Float Double Void Unit Nothing",literal:"true false null"},a={className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"@"},i={className:"subst",begin:"\\${",end:"}",contains:[e.C_NUMBER_MODE]},s={className:"variable",begin:"\\$"+e.UNDERSCORE_IDENT_RE},t={className:"string",variants:[{begin:'"""',end:'"""(?=[^"])',contains:[s,i]},{begin:"'",end:"'",illegal:/\n/,contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"',illegal:/\n/,contains:[e.BACKSLASH_ESCAPE,s,i]}]};i.contains.push(t);var r={className:"meta",begin:"@(?:file|property|field|get|set|receiver|param|setparam|delegate)\\s*:(?:\\s*"+e.UNDERSCORE_IDENT_RE+")?"},l={className:"meta",begin:"@"+e.UNDERSCORE_IDENT_RE,contains:[{begin:/\(/,end:/\)/,contains:[e.inherit(t,{className:"meta-string"})]}]},c=e.COMMENT("/\\*","\\*/",{contains:[e.C_BLOCK_COMMENT_MODE]}),o={variants:[{className:"type",begin:e.UNDERSCORE_IDENT_RE},{begin:/\(/,end:/\)/,contains:[]}]},d=o;return d.variants[1].contains=[o],o.variants[1].contains=[d],{name:"Kotlin",aliases:["kt"],keywords:n,contains:[e.COMMENT("/\\*\\*","\\*/",{relevance:0,contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.C_LINE_COMMENT_MODE,c,{className:"keyword",begin:/\b(break|continue|return|this)\b/,starts:{contains:[{className:"symbol",begin:/@\w+/}]}},a,r,l,{className:"function",beginKeywords:"fun",end:"[(]|$",returnBegin:!0,excludeEnd:!0,keywords:n,illegal:/fun\s+(<.*>)?[^\s\(]+(\s+[^\s\(]+)\s*=/,relevance:5,contains:[{begin:e.UNDERSCORE_IDENT_RE+"\\s*\\(",returnBegin:!0,relevance:0,contains:[e.UNDERSCORE_TITLE_MODE]},{className:"type",begin://,keywords:"reified",relevance:0},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:n,relevance:0,contains:[{begin:/:/,end:/[=,\/]/,endsWithParent:!0,contains:[o,e.C_LINE_COMMENT_MODE,c],relevance:0},e.C_LINE_COMMENT_MODE,c,r,l,t,e.C_NUMBER_MODE]},c]},{className:"class",beginKeywords:"class interface trait",end:/[:\{(]|$/,excludeEnd:!0,illegal:"extends implements",contains:[{beginKeywords:"public protected internal private constructor"},e.UNDERSCORE_TITLE_MODE,{className:"type",begin://,excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:/[,:]\s*/,end:/[<\(,]|$/,excludeBegin:!0,returnEnd:!0},r,l]},t,{className:"meta",begin:"^#!/usr/bin/env",end:"$",illegal:"\n"},{className:"number",begin:"\\b(0[bB]([01]+[01_]+[01]+|[01]+)|0[xX]([a-fA-F0-9]+[a-fA-F0-9_]+[a-fA-F0-9]+|[a-fA-F0-9]+)|(([\\d]+[\\d_]+[\\d]+|[\\d]+)(\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))?|\\.([\\d]+[\\d_]+[\\d]+|[\\d]+))([eE][-+]?\\d+)?)[lLfF]?",relevance:0}]}}}()); +hljs.registerLanguage("less",function(){"use strict";return function(e){var n="([\\w-]+|@{[\\w-]+})",a=[],s=[],t=function(e){return{className:"string",begin:"~?"+e+".*?"+e}},r=function(e,n,a){return{className:e,begin:n,relevance:a}},i={begin:"\\(",end:"\\)",contains:s,relevance:0};s.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t("'"),t('"'),e.CSS_NUMBER_MODE,{begin:"(url|data-uri)\\(",starts:{className:"string",end:"[\\)\\n]",excludeEnd:!0}},r("number","#[0-9A-Fa-f]+\\b"),i,r("variable","@@?[\\w-]+",10),r("variable","@{[\\w-]+}"),r("built_in","~?`[^`]*?`"),{className:"attribute",begin:"[\\w-]+\\s*:",end:":",returnBegin:!0,excludeEnd:!0},{className:"meta",begin:"!important"});var c=s.concat({begin:"{",end:"}",contains:a}),l={beginKeywords:"when",endsWithParent:!0,contains:[{beginKeywords:"and not"}].concat(s)},o={begin:n+"\\s*:",returnBegin:!0,end:"[;}]",relevance:0,contains:[{className:"attribute",begin:n,end:":",excludeEnd:!0,starts:{endsWithParent:!0,illegal:"[<=$]",relevance:0,contains:s}}]},g={className:"keyword",begin:"@(import|media|charset|font-face|(-[a-z]+-)?keyframes|supports|document|namespace|page|viewport|host)\\b",starts:{end:"[;{}]",returnEnd:!0,contains:s,relevance:0}},d={className:"variable",variants:[{begin:"@[\\w-]+\\s*:",relevance:15},{begin:"@[\\w-]+"}],starts:{end:"[;}]",returnEnd:!0,contains:c}},b={variants:[{begin:"[\\.#:&\\[>]",end:"[;{}]"},{begin:n,end:"{"}],returnBegin:!0,returnEnd:!0,illegal:"[<='$\"]",relevance:0,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,l,r("keyword","all\\b"),r("variable","@{[\\w-]+}"),r("selector-tag",n+"%?",0),r("selector-id","#"+n),r("selector-class","\\."+n,0),r("selector-tag","&",0),{className:"selector-attr",begin:"\\[",end:"\\]"},{className:"selector-pseudo",begin:/:(:)?[a-zA-Z0-9\_\-\+\(\)"'.]+/},{begin:"\\(",end:"\\)",contains:c},{begin:"!important"}]};return a.push(e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,g,d,o,b),{name:"Less",case_insensitive:!0,illegal:"[=>'/<($\"]",contains:a}}}()); +hljs.registerLanguage("lua",function(){"use strict";return function(e){var t={begin:"\\[=*\\[",end:"\\]=*\\]",contains:["self"]},a=[e.COMMENT("--(?!\\[=*\\[)","$"),e.COMMENT("--\\[=*\\[","\\]=*\\]",{contains:[t],relevance:10})];return{name:"Lua",keywords:{$pattern:e.UNDERSCORE_IDENT_RE,literal:"true false nil",keyword:"and break do else elseif end for goto if in local not or repeat return then until while",built_in:"_G _ENV _VERSION __index __newindex __mode __call __metatable __tostring __len __gc __add __sub __mul __div __mod __pow __concat __unm __eq __lt __le assert collectgarbage dofile error getfenv getmetatable ipairs load loadfile loadstring module next pairs pcall print rawequal rawget rawset require select setfenv setmetatable tonumber tostring type unpack xpcall arg self coroutine resume yield status wrap create running debug getupvalue debug sethook getmetatable gethook setmetatable setlocal traceback setfenv getinfo setupvalue getlocal getregistry getfenv io lines write close flush open output type read stderr stdin input stdout popen tmpfile math log max acos huge ldexp pi cos tanh pow deg tan cosh sinh random randomseed frexp ceil floor rad abs sqrt modf asin min mod fmod log10 atan2 exp sin atan os exit setlocale date getenv difftime remove time clock tmpname rename execute package preload loadlib loaded loaders cpath config path seeall string sub upper len gfind rep find match char dump gmatch reverse byte format gsub lower table setn insert getn foreachi maxn foreach concat sort remove"},contains:a.concat([{className:"function",beginKeywords:"function",end:"\\)",contains:[e.inherit(e.TITLE_MODE,{begin:"([_a-zA-Z]\\w*\\.)*([_a-zA-Z]\\w*:)?[_a-zA-Z]\\w*"}),{className:"params",begin:"\\(",endsWithParent:!0,contains:a}].concat(a)},e.C_NUMBER_MODE,e.APOS_STRING_MODE,e.QUOTE_STRING_MODE,{className:"string",begin:"\\[=*\\[",end:"\\]=*\\]",contains:[t],relevance:5}])}}}()); +hljs.registerLanguage("makefile",function(){"use strict";return function(e){var i={className:"variable",variants:[{begin:"\\$\\("+e.UNDERSCORE_IDENT_RE+"\\)",contains:[e.BACKSLASH_ESCAPE]},{begin:/\$[@%`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"",relevance:10,contains:[a,i,t,s,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"",contains:[a,s,i,t]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:")",end:">",keywords:{name:"style"},contains:[c],starts:{end:"",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:")",end:">",keywords:{name:"script"},contains:[c],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:"",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},c]}]}}}()); +hljs.registerLanguage("markdown",function(){"use strict";return function(n){const e={begin:"<",end:">",subLanguage:"xml",relevance:0},a={begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},i={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},s={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};i.contains.push(s),s.contains.push(i);var c=[e,a];return i.contains=i.contains.concat(c),s.contains=s.contains.concat(c),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:c=c.concat(i,s)},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:c}]}]},e,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:c,end:"$"},{className:"code",variants:[{begin:"(`{3,})(.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})(.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}}()); +hljs.registerLanguage("nginx",function(){"use strict";return function(e){var n={className:"variable",variants:[{begin:/\$\d+/},{begin:/\$\{/,end:/}/},{begin:"[\\$\\@]"+e.UNDERSCORE_IDENT_RE}]},a={endsWithParent:!0,keywords:{$pattern:"[a-z/_]+",literal:"on off yes no true false none blocked debug info notice warn error crit select break last permanent redirect kqueue rtsig epoll poll /dev/poll"},relevance:0,illegal:"=>",contains:[e.HASH_COMMENT_MODE,{className:"string",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:/"/,end:/"/},{begin:/'/,end:/'/}]},{begin:"([a-z]+):/",end:"\\s",endsWithParent:!0,excludeEnd:!0,contains:[n]},{className:"regexp",contains:[e.BACKSLASH_ESCAPE,n],variants:[{begin:"\\s\\^",end:"\\s|{|;",returnEnd:!0},{begin:"~\\*?\\s+",end:"\\s|{|;",returnEnd:!0},{begin:"\\*(\\.[a-z\\-]+)+"},{begin:"([a-z\\-]+\\.)+\\*"}]},{className:"number",begin:"\\b\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}(:\\d{1,5})?\\b"},{className:"number",begin:"\\b\\d+[kKmMgGdshdwy]*\\b",relevance:0},n]};return{name:"Nginx config",aliases:["nginxconf"],contains:[e.HASH_COMMENT_MODE,{begin:e.UNDERSCORE_IDENT_RE+"\\s+{",returnBegin:!0,end:"{",contains:[{className:"section",begin:e.UNDERSCORE_IDENT_RE}],relevance:0},{begin:e.UNDERSCORE_IDENT_RE+"\\s",end:";|{",returnBegin:!0,contains:[{className:"attribute",begin:e.UNDERSCORE_IDENT_RE,starts:a}],relevance:0}],illegal:"[^\\s\\}]"}}}()); +hljs.registerLanguage("objectivec",function(){"use strict";return function(e){var n=/[a-zA-Z@][a-zA-Z0-9_]*/,_={$pattern:n,keyword:"@interface @class @protocol @implementation"};return{name:"Objective-C",aliases:["mm","objc","obj-c"],keywords:{$pattern:n,keyword:"int float while char export sizeof typedef const struct for union unsigned long volatile static bool mutable if do return goto void enum else break extern asm case short default double register explicit signed typename this switch continue wchar_t inline readonly assign readwrite self @synchronized id typeof nonatomic super unichar IBOutlet IBAction strong weak copy in out inout bycopy byref oneway __strong __weak __block __autoreleasing @private @protected @public @try @property @end @throw @catch @finally @autoreleasepool @synthesize @dynamic @selector @optional @required @encode @package @import @defs @compatibility_alias __bridge __bridge_transfer __bridge_retained __bridge_retain __covariant __contravariant __kindof _Nonnull _Nullable _Null_unspecified __FUNCTION__ __PRETTY_FUNCTION__ __attribute__ getter setter retain unsafe_unretained nonnull nullable null_unspecified null_resettable class instancetype NS_DESIGNATED_INITIALIZER NS_UNAVAILABLE NS_REQUIRES_SUPER NS_RETURNS_INNER_POINTER NS_INLINE NS_AVAILABLE NS_DEPRECATED NS_ENUM NS_OPTIONS NS_SWIFT_UNAVAILABLE NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_END NS_REFINED_FOR_SWIFT NS_SWIFT_NAME NS_SWIFT_NOTHROW NS_DURING NS_HANDLER NS_ENDHANDLER NS_VALUERETURN NS_VOIDRETURN",literal:"false true FALSE TRUE nil YES NO NULL",built_in:"BOOL dispatch_once_t dispatch_queue_t dispatch_sync dispatch_async dispatch_once"},illegal:"/,end:/$/,illegal:"\\n"},e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE]},{className:"class",begin:"("+_.keyword.split(" ").join("|")+")\\b",end:"({|$)",excludeEnd:!0,keywords:_,contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"\\."+e.UNDERSCORE_IDENT_RE,relevance:0}]}}}()); +hljs.registerLanguage("perl",function(){"use strict";return function(e){var n={$pattern:/[\w.]+/,keyword:"getpwent getservent quotemeta msgrcv scalar kill dbmclose undef lc ma syswrite tr send umask sysopen shmwrite vec qx utime local oct semctl localtime readpipe do return format read sprintf dbmopen pop getpgrp not getpwnam rewinddir qq fileno qw endprotoent wait sethostent bless s|0 opendir continue each sleep endgrent shutdown dump chomp connect getsockname die socketpair close flock exists index shmget sub for endpwent redo lstat msgctl setpgrp abs exit select print ref gethostbyaddr unshift fcntl syscall goto getnetbyaddr join gmtime symlink semget splice x|0 getpeername recv log setsockopt cos last reverse gethostbyname getgrnam study formline endhostent times chop length gethostent getnetent pack getprotoent getservbyname rand mkdir pos chmod y|0 substr endnetent printf next open msgsnd readdir use unlink getsockopt getpriority rindex wantarray hex system getservbyport endservent int chr untie rmdir prototype tell listen fork shmread ucfirst setprotoent else sysseek link getgrgid shmctl waitpid unpack getnetbyname reset chdir grep split require caller lcfirst until warn while values shift telldir getpwuid my getprotobynumber delete and sort uc defined srand accept package seekdir getprotobyname semop our rename seek if q|0 chroot sysread setpwent no crypt getc chown sqrt write setnetent setpriority foreach tie sin msgget map stat getlogin unless elsif truncate exec keys glob tied closedir ioctl socket readlink eval xor readline binmode setservent eof ord bind alarm pipe atan2 getgrent exp time push setgrent gt lt or ne m|0 break given say state when"},t={className:"subst",begin:"[$@]\\{",end:"\\}",keywords:n},s={begin:"->{",end:"}"},r={variants:[{begin:/\$\d/},{begin:/[\$%@](\^\w\b|#\w+(::\w+)*|{\w+}|\w+(::\w*)*)/},{begin:/[\$%@][^\s\w{]/,relevance:0}]},i=[e.BACKSLASH_ESCAPE,t,r],a=[r,e.HASH_COMMENT_MODE,e.COMMENT("^\\=\\w","\\=cut",{endsWithParent:!0}),s,{className:"string",contains:i,variants:[{begin:"q[qwxr]?\\s*\\(",end:"\\)",relevance:5},{begin:"q[qwxr]?\\s*\\[",end:"\\]",relevance:5},{begin:"q[qwxr]?\\s*\\{",end:"\\}",relevance:5},{begin:"q[qwxr]?\\s*\\|",end:"\\|",relevance:5},{begin:"q[qwxr]?\\s*\\<",end:"\\>",relevance:5},{begin:"qw\\s+q",end:"q",relevance:5},{begin:"'",end:"'",contains:[e.BACKSLASH_ESCAPE]},{begin:'"',end:'"'},{begin:"`",end:"`",contains:[e.BACKSLASH_ESCAPE]},{begin:"{\\w+}",contains:[],relevance:0},{begin:"-?\\w+\\s*\\=\\>",contains:[],relevance:0}]},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\/\\/|"+e.RE_STARTERS_RE+"|\\b(split|return|print|reverse|grep)\\b)\\s*",keywords:"split return print reverse grep",relevance:0,contains:[e.HASH_COMMENT_MODE,{className:"regexp",begin:"(s|tr|y)/(\\\\.|[^/])*/(\\\\.|[^/])*/[a-z]*",relevance:10},{className:"regexp",begin:"(m|qr)?/",end:"/[a-z]*",contains:[e.BACKSLASH_ESCAPE],relevance:0}]},{className:"function",beginKeywords:"sub",end:"(\\s*\\(.*?\\))?[;{]",excludeEnd:!0,relevance:5,contains:[e.TITLE_MODE]},{begin:"-\\w\\b",relevance:0},{begin:"^__DATA__$",end:"^__END__$",subLanguage:"mojolicious",contains:[{begin:"^@@.*",end:"$",className:"comment"}]}];return t.contains=a,s.contains=a,{name:"Perl",aliases:["pl","pm"],keywords:n,contains:a}}}()); +hljs.registerLanguage("php",function(){"use strict";return function(e){var r={begin:"\\$+[a-zA-Z_-ÿ][a-zA-Z0-9_-ÿ]*"},t={className:"meta",variants:[{begin:/<\?php/,relevance:10},{begin:/<\?[=]?/},{begin:/\?>/}]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:'b"',end:'"'},{begin:"b'",end:"'"},e.inherit(e.APOS_STRING_MODE,{illegal:null}),e.inherit(e.QUOTE_STRING_MODE,{illegal:null})]},n={variants:[e.BINARY_NUMBER_MODE,e.C_NUMBER_MODE]},i={keyword:"__CLASS__ __DIR__ __FILE__ __FUNCTION__ __LINE__ __METHOD__ __NAMESPACE__ __TRAIT__ die echo exit include include_once print require require_once array abstract and as binary bool boolean break callable case catch class clone const continue declare default do double else elseif empty enddeclare endfor endforeach endif endswitch endwhile eval extends final finally float for foreach from global goto if implements instanceof insteadof int integer interface isset iterable list new object or private protected public real return string switch throw trait try unset use var void while xor yield",literal:"false null true",built_in:"Error|0 AppendIterator ArgumentCountError ArithmeticError ArrayIterator ArrayObject AssertionError BadFunctionCallException BadMethodCallException CachingIterator CallbackFilterIterator CompileError Countable DirectoryIterator DivisionByZeroError DomainException EmptyIterator ErrorException Exception FilesystemIterator FilterIterator GlobIterator InfiniteIterator InvalidArgumentException IteratorIterator LengthException LimitIterator LogicException MultipleIterator NoRewindIterator OutOfBoundsException OutOfRangeException OuterIterator OverflowException ParentIterator ParseError RangeException RecursiveArrayIterator RecursiveCachingIterator RecursiveCallbackFilterIterator RecursiveDirectoryIterator RecursiveFilterIterator RecursiveIterator RecursiveIteratorIterator RecursiveRegexIterator RecursiveTreeIterator RegexIterator RuntimeException SeekableIterator SplDoublyLinkedList SplFileInfo SplFileObject SplFixedArray SplHeap SplMaxHeap SplMinHeap SplObjectStorage SplObserver SplObserver SplPriorityQueue SplQueue SplStack SplSubject SplSubject SplTempFileObject TypeError UnderflowException UnexpectedValueException ArrayAccess Closure Generator Iterator IteratorAggregate Serializable Throwable Traversable WeakReference Directory __PHP_Incomplete_Class parent php_user_filter self static stdClass"};return{aliases:["php","php3","php4","php5","php6","php7"],case_insensitive:!0,keywords:i,contains:[e.HASH_COMMENT_MODE,e.COMMENT("//","$",{contains:[t]}),e.COMMENT("/\\*","\\*/",{contains:[{className:"doctag",begin:"@[A-Za-z]+"}]}),e.COMMENT("__halt_compiler.+?;",!1,{endsWithParent:!0,keywords:"__halt_compiler"}),{className:"string",begin:/<<<['"]?\w+['"]?$/,end:/^\w+;?$/,contains:[e.BACKSLASH_ESCAPE,{className:"subst",variants:[{begin:/\$\w+/},{begin:/\{\$/,end:/\}/}]}]},t,{className:"keyword",begin:/\$this\b/},r,{begin:/(::|->)+[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*/},{className:"function",beginKeywords:"fn function",end:/[;{]/,excludeEnd:!0,illegal:"[$%\\[]",contains:[e.UNDERSCORE_TITLE_MODE,{className:"params",begin:"\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0,keywords:i,contains:["self",r,e.C_BLOCK_COMMENT_MODE,a,n]}]},{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,illegal:/[:\(\$"]/,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"namespace",end:";",illegal:/[\.']/,contains:[e.UNDERSCORE_TITLE_MODE]},{beginKeywords:"use",end:";",contains:[e.UNDERSCORE_TITLE_MODE]},{begin:"=>"},a,n]}}}()); +hljs.registerLanguage("php-template",function(){"use strict";return function(n){return{name:"PHP template",subLanguage:"xml",contains:[{begin:/<\?(php|=)?/,end:/\?>/,subLanguage:"php",contains:[{begin:"/\\*",end:"\\*/",skip:!0},{begin:'b"',end:'"',skip:!0},{begin:"b'",end:"'",skip:!0},n.inherit(n.APOS_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0}),n.inherit(n.QUOTE_STRING_MODE,{illegal:null,className:null,contains:null,skip:!0})]}]}}}()); +hljs.registerLanguage("plaintext",function(){"use strict";return function(t){return{name:"Plain text",aliases:["text","txt"],disableAutodetect:!0}}}()); +hljs.registerLanguage("properties",function(){"use strict";return function(e){var n="[ \\t\\f]*",t="("+n+"[:=]"+n+"|[ \\t\\f]+)",a="([^\\\\:= \\t\\f\\n]|\\\\.)+",s={end:t,relevance:0,starts:{className:"string",end:/$/,relevance:0,contains:[{begin:"\\\\\\n"}]}};return{name:".properties",case_insensitive:!0,illegal:/\S/,contains:[e.COMMENT("^\\s*[!#]","$"),{begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+"+t,returnBegin:!0,contains:[{className:"attr",begin:"([^\\\\\\W:= \\t\\f\\n]|\\\\.)+",endsParent:!0,relevance:0}],starts:s},{begin:a+t,returnBegin:!0,relevance:0,contains:[{className:"meta",begin:a,endsParent:!0,relevance:0}],starts:s},{className:"attr",relevance:0,begin:a+n+"$"}]}}}()); +hljs.registerLanguage("python",function(){"use strict";return function(e){var n={keyword:"and elif is global as in if from raise for except finally print import pass return exec else break not with class assert yield try while continue del or def lambda async await nonlocal|10",built_in:"Ellipsis NotImplemented",literal:"False None True"},a={className:"meta",begin:/^(>>>|\.\.\.) /},i={className:"subst",begin:/\{/,end:/\}/,keywords:n,illegal:/#/},s={begin:/\{\{/,relevance:0},r={className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:/(u|b)?r?'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(u|b)?r?"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a],relevance:10},{begin:/(fr|rf|f)'''/,end:/'''/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(fr|rf|f)"""/,end:/"""/,contains:[e.BACKSLASH_ESCAPE,a,s,i]},{begin:/(u|r|ur)'/,end:/'/,relevance:10},{begin:/(u|r|ur)"/,end:/"/,relevance:10},{begin:/(b|br)'/,end:/'/},{begin:/(b|br)"/,end:/"/},{begin:/(fr|rf|f)'/,end:/'/,contains:[e.BACKSLASH_ESCAPE,s,i]},{begin:/(fr|rf|f)"/,end:/"/,contains:[e.BACKSLASH_ESCAPE,s,i]},e.APOS_STRING_MODE,e.QUOTE_STRING_MODE]},l={className:"number",relevance:0,variants:[{begin:e.BINARY_NUMBER_RE+"[lLjJ]?"},{begin:"\\b(0o[0-7]+)[lLjJ]?"},{begin:e.C_NUMBER_RE+"[lLjJ]?"}]},t={className:"params",variants:[{begin:/\(\s*\)/,skip:!0,className:null},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,contains:["self",a,l,r,e.HASH_COMMENT_MODE]}]};return i.contains=[r,l,a],{name:"Python",aliases:["py","gyp","ipython"],keywords:n,illegal:/(<\/|->|\?)|=>/,contains:[a,l,{beginKeywords:"if",relevance:0},r,e.HASH_COMMENT_MODE,{variants:[{className:"function",beginKeywords:"def"},{className:"class",beginKeywords:"class"}],end:/:/,illegal:/[${=;\n,]/,contains:[e.UNDERSCORE_TITLE_MODE,t,{begin:/->/,endsWithParent:!0,keywords:"None"}]},{className:"meta",begin:/^[\t ]*@/,end:/$/},{begin:/\b(print|exec)\(/}]}}}()); +hljs.registerLanguage("python-repl",function(){"use strict";return function(n){return{aliases:["pycon"],contains:[{className:"meta",starts:{end:/ |$/,starts:{end:"$",subLanguage:"python"}},variants:[{begin:/^>>>(?=[ ]|$)/},{begin:/^\.\.\.(?=[ ]|$)/}]}]}}}()); +hljs.registerLanguage("ruby",function(){"use strict";return function(e){var n="[a-zA-Z_]\\w*[!?=]?|[-+~]\\@|<<|>>|=~|===?|<=>|[<>]=?|\\*\\*|[-/+%^&*~`|]|\\[\\]=?",a={keyword:"and then defined module in return redo if BEGIN retry end for self when next until do begin unless END rescue else break undef not super class case require yield alias while ensure elsif or include attr_reader attr_writer attr_accessor",literal:"true false nil"},s={className:"doctag",begin:"@[A-Za-z]+"},i={begin:"#<",end:">"},r=[e.COMMENT("#","$",{contains:[s]}),e.COMMENT("^\\=begin","^\\=end",{contains:[s],relevance:10}),e.COMMENT("^__END__","\\n$")],c={className:"subst",begin:"#\\{",end:"}",keywords:a},t={className:"string",contains:[e.BACKSLASH_ESCAPE,c],variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/`/,end:/`/},{begin:"%[qQwWx]?\\(",end:"\\)"},{begin:"%[qQwWx]?\\[",end:"\\]"},{begin:"%[qQwWx]?{",end:"}"},{begin:"%[qQwWx]?<",end:">"},{begin:"%[qQwWx]?/",end:"/"},{begin:"%[qQwWx]?%",end:"%"},{begin:"%[qQwWx]?-",end:"-"},{begin:"%[qQwWx]?\\|",end:"\\|"},{begin:/\B\?(\\\d{1,3}|\\x[A-Fa-f0-9]{1,2}|\\u[A-Fa-f0-9]{4}|\\?\S)\b/},{begin:/<<[-~]?'?(\w+)(?:.|\n)*?\n\s*\1\b/,returnBegin:!0,contains:[{begin:/<<[-~]?'?/},e.END_SAME_AS_BEGIN({begin:/(\w+)/,end:/(\w+)/,contains:[e.BACKSLASH_ESCAPE,c]})]}]},b={className:"params",begin:"\\(",end:"\\)",endsParent:!0,keywords:a},d=[t,i,{className:"class",beginKeywords:"class module",end:"$|;",illegal:/=/,contains:[e.inherit(e.TITLE_MODE,{begin:"[A-Za-z_]\\w*(::\\w+)*(\\?|\\!)?"}),{begin:"<\\s*",contains:[{begin:"("+e.IDENT_RE+"::)?"+e.IDENT_RE}]}].concat(r)},{className:"function",beginKeywords:"def",end:"$|;",contains:[e.inherit(e.TITLE_MODE,{begin:n}),b].concat(r)},{begin:e.IDENT_RE+"::"},{className:"symbol",begin:e.UNDERSCORE_IDENT_RE+"(\\!|\\?)?:",relevance:0},{className:"symbol",begin:":(?!\\s)",contains:[t,{begin:n}],relevance:0},{className:"number",begin:"(\\b0[0-7_]+)|(\\b0x[0-9a-fA-F_]+)|(\\b[1-9][0-9_]*(\\.[0-9_]+)?)|[0_]\\b",relevance:0},{begin:"(\\$\\W)|((\\$|\\@\\@?)(\\w+))"},{className:"params",begin:/\|/,end:/\|/,keywords:a},{begin:"("+e.RE_STARTERS_RE+"|unless)\\s*",keywords:"unless",contains:[i,{className:"regexp",contains:[e.BACKSLASH_ESCAPE,c],illegal:/\n/,variants:[{begin:"/",end:"/[a-z]*"},{begin:"%r{",end:"}[a-z]*"},{begin:"%r\\(",end:"\\)[a-z]*"},{begin:"%r!",end:"![a-z]*"},{begin:"%r\\[",end:"\\][a-z]*"}]}].concat(r),relevance:0}].concat(r);c.contains=d,b.contains=d;var g=[{begin:/^\s*=>/,starts:{end:"$",contains:d}},{className:"meta",begin:"^([>?]>|[\\w#]+\\(\\w+\\):\\d+:\\d+>|(\\w+-)?\\d+\\.\\d+\\.\\d(p\\d+)?[^>]+>)",starts:{end:"$",contains:d}}];return{name:"Ruby",aliases:["rb","gemspec","podspec","thor","irb"],keywords:a,illegal:/\/\*/,contains:r.concat(g).concat(d)}}}()); +hljs.registerLanguage("rust",function(){"use strict";return function(e){var n="([ui](8|16|32|64|128|size)|f(32|64))?",t="drop i8 i16 i32 i64 i128 isize u8 u16 u32 u64 u128 usize f32 f64 str char bool Box Option Result String Vec Copy Send Sized Sync Drop Fn FnMut FnOnce ToOwned Clone Debug PartialEq PartialOrd Eq Ord AsRef AsMut Into From Default Iterator Extend IntoIterator DoubleEndedIterator ExactSizeIterator SliceConcatExt ToString assert! assert_eq! bitflags! bytes! cfg! col! concat! concat_idents! debug_assert! debug_assert_eq! env! panic! file! format! format_args! include_bin! include_str! line! local_data_key! module_path! option_env! print! println! select! stringify! try! unimplemented! unreachable! vec! write! writeln! macro_rules! assert_ne! debug_assert_ne!";return{name:"Rust",aliases:["rs"],keywords:{$pattern:e.IDENT_RE+"!?",keyword:"abstract as async await become box break const continue crate do dyn else enum extern false final fn for if impl in let loop macro match mod move mut override priv pub ref return self Self static struct super trait true try type typeof unsafe unsized use virtual where while yield",literal:"true false Some None Ok Err",built_in:t},illegal:""}]}}}()); +hljs.registerLanguage("scss",function(){"use strict";return function(e){var t={className:"variable",begin:"(\\$[a-zA-Z-][a-zA-Z0-9_-]*)\\b"},i={className:"number",begin:"#[0-9A-Fa-f]+"};return e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,e.C_BLOCK_COMMENT_MODE,{name:"SCSS",case_insensitive:!0,illegal:"[=/|']",contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"selector-id",begin:"\\#[A-Za-z0-9_-]+",relevance:0},{className:"selector-class",begin:"\\.[A-Za-z0-9_-]+",relevance:0},{className:"selector-attr",begin:"\\[",end:"\\]",illegal:"$"},{className:"selector-tag",begin:"\\b(a|abbr|acronym|address|area|article|aside|audio|b|base|big|blockquote|body|br|button|canvas|caption|cite|code|col|colgroup|command|datalist|dd|del|details|dfn|div|dl|dt|em|embed|fieldset|figcaption|figure|footer|form|frame|frameset|(h[1-6])|head|header|hgroup|hr|html|i|iframe|img|input|ins|kbd|keygen|label|legend|li|link|map|mark|meta|meter|nav|noframes|noscript|object|ol|optgroup|option|output|p|param|pre|progress|q|rp|rt|ruby|samp|script|section|select|small|span|strike|strong|style|sub|sup|table|tbody|td|textarea|tfoot|th|thead|time|title|tr|tt|ul|var|video)\\b",relevance:0},{className:"selector-pseudo",begin:":(visited|valid|root|right|required|read-write|read-only|out-range|optional|only-of-type|only-child|nth-of-type|nth-last-of-type|nth-last-child|nth-child|not|link|left|last-of-type|last-child|lang|invalid|indeterminate|in-range|hover|focus|first-of-type|first-line|first-letter|first-child|first|enabled|empty|disabled|default|checked|before|after|active)"},{className:"selector-pseudo",begin:"::(after|before|choices|first-letter|first-line|repeat-index|repeat-item|selection|value)"},t,{className:"attribute",begin:"\\b(src|z-index|word-wrap|word-spacing|word-break|width|widows|white-space|visibility|vertical-align|unicode-bidi|transition-timing-function|transition-property|transition-duration|transition-delay|transition|transform-style|transform-origin|transform|top|text-underline-position|text-transform|text-shadow|text-rendering|text-overflow|text-indent|text-decoration-style|text-decoration-line|text-decoration-color|text-decoration|text-align-last|text-align|tab-size|table-layout|right|resize|quotes|position|pointer-events|perspective-origin|perspective|page-break-inside|page-break-before|page-break-after|padding-top|padding-right|padding-left|padding-bottom|padding|overflow-y|overflow-x|overflow-wrap|overflow|outline-width|outline-style|outline-offset|outline-color|outline|orphans|order|opacity|object-position|object-fit|normal|none|nav-up|nav-right|nav-left|nav-index|nav-down|min-width|min-height|max-width|max-height|mask|marks|margin-top|margin-right|margin-left|margin-bottom|margin|list-style-type|list-style-position|list-style-image|list-style|line-height|letter-spacing|left|justify-content|initial|inherit|ime-mode|image-orientation|image-resolution|image-rendering|icon|hyphens|height|font-weight|font-variant-ligatures|font-variant|font-style|font-stretch|font-size-adjust|font-size|font-language-override|font-kerning|font-feature-settings|font-family|font|float|flex-wrap|flex-shrink|flex-grow|flex-flow|flex-direction|flex-basis|flex|filter|empty-cells|display|direction|cursor|counter-reset|counter-increment|content|column-width|column-span|column-rule-width|column-rule-style|column-rule-color|column-rule|column-gap|column-fill|column-count|columns|color|clip-path|clip|clear|caption-side|break-inside|break-before|break-after|box-sizing|box-shadow|box-decoration-break|bottom|border-width|border-top-width|border-top-style|border-top-right-radius|border-top-left-radius|border-top-color|border-top|border-style|border-spacing|border-right-width|border-right-style|border-right-color|border-right|border-radius|border-left-width|border-left-style|border-left-color|border-left|border-image-width|border-image-source|border-image-slice|border-image-repeat|border-image-outset|border-image|border-color|border-collapse|border-bottom-width|border-bottom-style|border-bottom-right-radius|border-bottom-left-radius|border-bottom-color|border-bottom|border|background-size|background-repeat|background-position|background-origin|background-image|background-color|background-clip|background-attachment|background-blend-mode|background|backface-visibility|auto|animation-timing-function|animation-play-state|animation-name|animation-iteration-count|animation-fill-mode|animation-duration|animation-direction|animation-delay|animation|align-self|align-items|align-content)\\b",illegal:"[^\\s]"},{begin:"\\b(whitespace|wait|w-resize|visible|vertical-text|vertical-ideographic|uppercase|upper-roman|upper-alpha|underline|transparent|top|thin|thick|text|text-top|text-bottom|tb-rl|table-header-group|table-footer-group|sw-resize|super|strict|static|square|solid|small-caps|separate|se-resize|scroll|s-resize|rtl|row-resize|ridge|right|repeat|repeat-y|repeat-x|relative|progress|pointer|overline|outside|outset|oblique|nowrap|not-allowed|normal|none|nw-resize|no-repeat|no-drop|newspaper|ne-resize|n-resize|move|middle|medium|ltr|lr-tb|lowercase|lower-roman|lower-alpha|loose|list-item|line|line-through|line-edge|lighter|left|keep-all|justify|italic|inter-word|inter-ideograph|inside|inset|inline|inline-block|inherit|inactive|ideograph-space|ideograph-parenthesis|ideograph-numeric|ideograph-alpha|horizontal|hidden|help|hand|groove|fixed|ellipsis|e-resize|double|dotted|distribute|distribute-space|distribute-letter|distribute-all-lines|disc|disabled|default|decimal|dashed|crosshair|collapse|col-resize|circle|char|center|capitalize|break-word|break-all|bottom|both|bolder|bold|block|bidi-override|below|baseline|auto|always|all-scroll|absolute|table|table-cell)\\b"},{begin:":",end:";",contains:[t,i,e.CSS_NUMBER_MODE,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,{className:"meta",begin:"!important"}]},{begin:"@(page|font-face)",lexemes:"@[a-z-]+",keywords:"@page @font-face"},{begin:"@",end:"[{;]",returnBegin:!0,keywords:"and or not only",contains:[{begin:"@[a-z-]+",className:"keyword"},t,e.QUOTE_STRING_MODE,e.APOS_STRING_MODE,i,e.CSS_NUMBER_MODE]}]}}}()); +hljs.registerLanguage("shell",function(){"use strict";return function(s){return{name:"Shell Session",aliases:["console"],contains:[{className:"meta",begin:"^\\s{0,3}[/\\w\\d\\[\\]()@-]*[>%$#]",starts:{end:"$",subLanguage:"bash"}}]}}}()); +hljs.registerLanguage("sql",function(){"use strict";return function(e){var t=e.COMMENT("--","$");return{name:"SQL",case_insensitive:!0,illegal:/[<>{}*]/,contains:[{beginKeywords:"begin end start commit rollback savepoint lock alter create drop rename call delete do handler insert load replace select truncate update set show pragma grant merge describe use explain help declare prepare execute deallocate release unlock purge reset change stop analyze cache flush optimize repair kill install uninstall checksum restore check backup revoke comment values with",end:/;/,endsWithParent:!0,keywords:{$pattern:/[\w\.]+/,keyword:"as abort abs absolute acc acce accep accept access accessed accessible account acos action activate add addtime admin administer advanced advise aes_decrypt aes_encrypt after agent aggregate ali alia alias all allocate allow alter always analyze ancillary and anti any anydata anydataset anyschema anytype apply archive archived archivelog are as asc ascii asin assembly assertion associate asynchronous at atan atn2 attr attri attrib attribu attribut attribute attributes audit authenticated authentication authid authors auto autoallocate autodblink autoextend automatic availability avg backup badfile basicfile before begin beginning benchmark between bfile bfile_base big bigfile bin binary_double binary_float binlog bit_and bit_count bit_length bit_or bit_xor bitmap blob_base block blocksize body both bound bucket buffer_cache buffer_pool build bulk by byte byteordermark bytes cache caching call calling cancel capacity cascade cascaded case cast catalog category ceil ceiling chain change changed char_base char_length character_length characters characterset charindex charset charsetform charsetid check checksum checksum_agg child choose chr chunk class cleanup clear client clob clob_base clone close cluster_id cluster_probability cluster_set clustering coalesce coercibility col collate collation collect colu colum column column_value columns columns_updated comment commit compact compatibility compiled complete composite_limit compound compress compute concat concat_ws concurrent confirm conn connec connect connect_by_iscycle connect_by_isleaf connect_by_root connect_time connection consider consistent constant constraint constraints constructor container content contents context contributors controlfile conv convert convert_tz corr corr_k corr_s corresponding corruption cos cost count count_big counted covar_pop covar_samp cpu_per_call cpu_per_session crc32 create creation critical cross cube cume_dist curdate current current_date current_time current_timestamp current_user cursor curtime customdatum cycle data database databases datafile datafiles datalength date_add date_cache date_format date_sub dateadd datediff datefromparts datename datepart datetime2fromparts day day_to_second dayname dayofmonth dayofweek dayofyear days db_role_change dbtimezone ddl deallocate declare decode decompose decrement decrypt deduplicate def defa defau defaul default defaults deferred defi defin define degrees delayed delegate delete delete_all delimited demand dense_rank depth dequeue des_decrypt des_encrypt des_key_file desc descr descri describ describe descriptor deterministic diagnostics difference dimension direct_load directory disable disable_all disallow disassociate discardfile disconnect diskgroup distinct distinctrow distribute distributed div do document domain dotnet double downgrade drop dumpfile duplicate duration each edition editionable editions element ellipsis else elsif elt empty enable enable_all enclosed encode encoding encrypt end end-exec endian enforced engine engines enqueue enterprise entityescaping eomonth error errors escaped evalname evaluate event eventdata events except exception exceptions exchange exclude excluding execu execut execute exempt exists exit exp expire explain explode export export_set extended extent external external_1 external_2 externally extract failed failed_login_attempts failover failure far fast feature_set feature_value fetch field fields file file_name_convert filesystem_like_logging final finish first first_value fixed flash_cache flashback floor flush following follows for forall force foreign form forma format found found_rows freelist freelists freepools fresh from from_base64 from_days ftp full function general generated get get_format get_lock getdate getutcdate global global_name globally go goto grant grants greatest group group_concat group_id grouping grouping_id groups gtid_subtract guarantee guard handler hash hashkeys having hea head headi headin heading heap help hex hierarchy high high_priority hosts hour hours http id ident_current ident_incr ident_seed identified identity idle_time if ifnull ignore iif ilike ilm immediate import in include including increment index indexes indexing indextype indicator indices inet6_aton inet6_ntoa inet_aton inet_ntoa infile initial initialized initially initrans inmemory inner innodb input insert install instance instantiable instr interface interleaved intersect into invalidate invisible is is_free_lock is_ipv4 is_ipv4_compat is_not is_not_null is_used_lock isdate isnull isolation iterate java join json json_exists keep keep_duplicates key keys kill language large last last_day last_insert_id last_value lateral lax lcase lead leading least leaves left len lenght length less level levels library like like2 like4 likec limit lines link list listagg little ln load load_file lob lobs local localtime localtimestamp locate locator lock locked log log10 log2 logfile logfiles logging logical logical_reads_per_call logoff logon logs long loop low low_priority lower lpad lrtrim ltrim main make_set makedate maketime managed management manual map mapping mask master master_pos_wait match matched materialized max maxextents maximize maxinstances maxlen maxlogfiles maxloghistory maxlogmembers maxsize maxtrans md5 measures median medium member memcompress memory merge microsecond mid migration min minextents minimum mining minus minute minutes minvalue missing mod mode model modification modify module monitoring month months mount move movement multiset mutex name name_const names nan national native natural nav nchar nclob nested never new newline next nextval no no_write_to_binlog noarchivelog noaudit nobadfile nocheck nocompress nocopy nocycle nodelay nodiscardfile noentityescaping noguarantee nokeep nologfile nomapping nomaxvalue nominimize nominvalue nomonitoring none noneditionable nonschema noorder nopr nopro noprom nopromp noprompt norely noresetlogs noreverse normal norowdependencies noschemacheck noswitch not nothing notice notnull notrim novalidate now nowait nth_value nullif nulls num numb numbe nvarchar nvarchar2 object ocicoll ocidate ocidatetime ociduration ociinterval ociloblocator ocinumber ociref ocirefcursor ocirowid ocistring ocitype oct octet_length of off offline offset oid oidindex old on online only opaque open operations operator optimal optimize option optionally or oracle oracle_date oradata ord ordaudio orddicom orddoc order ordimage ordinality ordvideo organization orlany orlvary out outer outfile outline output over overflow overriding package pad parallel parallel_enable parameters parent parse partial partition partitions pascal passing password password_grace_time password_lock_time password_reuse_max password_reuse_time password_verify_function patch path patindex pctincrease pctthreshold pctused pctversion percent percent_rank percentile_cont percentile_disc performance period period_add period_diff permanent physical pi pipe pipelined pivot pluggable plugin policy position post_transaction pow power pragma prebuilt precedes preceding precision prediction prediction_cost prediction_details prediction_probability prediction_set prepare present preserve prior priority private private_sga privileges procedural procedure procedure_analyze processlist profiles project prompt protection public publishingservername purge quarter query quick quiesce quota quotename radians raise rand range rank raw read reads readsize rebuild record records recover recovery recursive recycle redo reduced ref reference referenced references referencing refresh regexp_like register regr_avgx regr_avgy regr_count regr_intercept regr_r2 regr_slope regr_sxx regr_sxy reject rekey relational relative relaylog release release_lock relies_on relocate rely rem remainder rename repair repeat replace replicate replication required reset resetlogs resize resource respect restore restricted result result_cache resumable resume retention return returning returns reuse reverse revoke right rlike role roles rollback rolling rollup round row row_count rowdependencies rowid rownum rows rtrim rules safe salt sample save savepoint sb1 sb2 sb4 scan schema schemacheck scn scope scroll sdo_georaster sdo_topo_geometry search sec_to_time second seconds section securefile security seed segment select self semi sequence sequential serializable server servererror session session_user sessions_per_user set sets settings sha sha1 sha2 share shared shared_pool short show shrink shutdown si_averagecolor si_colorhistogram si_featurelist si_positionalcolor si_stillimage si_texture siblings sid sign sin size size_t sizes skip slave sleep smalldatetimefromparts smallfile snapshot some soname sort soundex source space sparse spfile split sql sql_big_result sql_buffer_result sql_cache sql_calc_found_rows sql_small_result sql_variant_property sqlcode sqldata sqlerror sqlname sqlstate sqrt square standalone standby start starting startup statement static statistics stats_binomial_test stats_crosstab stats_ks_test stats_mode stats_mw_test stats_one_way_anova stats_t_test_ stats_t_test_indep stats_t_test_one stats_t_test_paired stats_wsr_test status std stddev stddev_pop stddev_samp stdev stop storage store stored str str_to_date straight_join strcmp strict string struct stuff style subdate subpartition subpartitions substitutable substr substring subtime subtring_index subtype success sum suspend switch switchoffset switchover sync synchronous synonym sys sys_xmlagg sysasm sysaux sysdate sysdatetimeoffset sysdba sysoper system system_user sysutcdatetime table tables tablespace tablesample tan tdo template temporary terminated tertiary_weights test than then thread through tier ties time time_format time_zone timediff timefromparts timeout timestamp timestampadd timestampdiff timezone_abbr timezone_minute timezone_region to to_base64 to_date to_days to_seconds todatetimeoffset trace tracking transaction transactional translate translation treat trigger trigger_nestlevel triggers trim truncate try_cast try_convert try_parse type ub1 ub2 ub4 ucase unarchived unbounded uncompress under undo unhex unicode uniform uninstall union unique unix_timestamp unknown unlimited unlock unnest unpivot unrecoverable unsafe unsigned until untrusted unusable unused update updated upgrade upped upper upsert url urowid usable usage use use_stored_outlines user user_data user_resources users using utc_date utc_timestamp uuid uuid_short validate validate_password_strength validation valist value values var var_samp varcharc vari varia variab variabl variable variables variance varp varraw varrawc varray verify version versions view virtual visible void wait wallet warning warnings week weekday weekofyear wellformed when whene whenev wheneve whenever where while whitespace window with within without work wrapped xdb xml xmlagg xmlattributes xmlcast xmlcolattval xmlelement xmlexists xmlforest xmlindex xmlnamespaces xmlpi xmlquery xmlroot xmlschema xmlserialize xmltable xmltype xor year year_to_month years yearweek",literal:"true false null unknown",built_in:"array bigint binary bit blob bool boolean char character date dec decimal float int int8 integer interval number numeric real record serial serial8 smallint text time timestamp tinyint varchar varchar2 varying void"},contains:[{className:"string",begin:"'",end:"'",contains:[{begin:"''"}]},{className:"string",begin:'"',end:'"',contains:[{begin:'""'}]},{className:"string",begin:"`",end:"`"},e.C_NUMBER_MODE,e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]},e.C_BLOCK_COMMENT_MODE,t,e.HASH_COMMENT_MODE]}}}()); +hljs.registerLanguage("swift",function(){"use strict";return function(e){var i={keyword:"#available #colorLiteral #column #else #elseif #endif #file #fileLiteral #function #if #imageLiteral #line #selector #sourceLocation _ __COLUMN__ __FILE__ __FUNCTION__ __LINE__ Any as as! as? associatedtype associativity break case catch class continue convenience default defer deinit didSet do dynamic dynamicType else enum extension fallthrough false fileprivate final for func get guard if import in indirect infix init inout internal is lazy left let mutating nil none nonmutating open operator optional override postfix precedence prefix private protocol Protocol public repeat required rethrows return right self Self set static struct subscript super switch throw throws true try try! try? Type typealias unowned var weak where while willSet",literal:"true false nil",built_in:"abs advance alignof alignofValue anyGenerator assert assertionFailure bridgeFromObjectiveC bridgeFromObjectiveCUnconditional bridgeToObjectiveC bridgeToObjectiveCUnconditional c compactMap contains count countElements countLeadingZeros debugPrint debugPrintln distance dropFirst dropLast dump encodeBitsAsWords enumerate equal fatalError filter find getBridgedObjectiveCType getVaList indices insertionSort isBridgedToObjectiveC isBridgedVerbatimToObjectiveC isUniquelyReferenced isUniquelyReferencedNonObjC join lazy lexicographicalCompare map max maxElement min minElement numericCast overlaps partition posix precondition preconditionFailure print println quickSort readLine reduce reflect reinterpretCast reverse roundUpToAlignment sizeof sizeofValue sort split startsWith stride strideof strideofValue swap toString transcode underestimateCount unsafeAddressOf unsafeBitCast unsafeDowncast unsafeUnwrap unsafeReflect withExtendedLifetime withObjectAtPlusZero withUnsafePointer withUnsafePointerToObject withUnsafeMutablePointer withUnsafeMutablePointers withUnsafePointer withUnsafePointers withVaList zip"},n=e.COMMENT("/\\*","\\*/",{contains:["self"]}),t={className:"subst",begin:/\\\(/,end:"\\)",keywords:i,contains:[]},a={className:"string",contains:[e.BACKSLASH_ESCAPE,t],variants:[{begin:/"""/,end:/"""/},{begin:/"/,end:/"/}]},r={className:"number",begin:"\\b([\\d_]+(\\.[\\deE_]+)?|0x[a-fA-F0-9_]+(\\.[a-fA-F0-9p_]+)?|0b[01_]+|0o[0-7_]+)\\b",relevance:0};return t.contains=[r],{name:"Swift",keywords:i,contains:[a,e.C_LINE_COMMENT_MODE,n,{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*[!?]"},{className:"type",begin:"\\b[A-Z][\\wÀ-ʸ']*",relevance:0},r,{className:"function",beginKeywords:"func",end:"{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][0-9A-Za-z$_]*/}),{begin://},{className:"params",begin:/\(/,end:/\)/,endsParent:!0,keywords:i,contains:["self",r,a,e.C_BLOCK_COMMENT_MODE,{begin:":"}],illegal:/["']/}],illegal:/\[|%/},{className:"class",beginKeywords:"struct protocol class extension enum",keywords:i,end:"\\{",excludeEnd:!0,contains:[e.inherit(e.TITLE_MODE,{begin:/[A-Za-z$_][\u00C0-\u02B80-9A-Za-z$_]*/})]},{className:"meta",begin:"(@discardableResult|@warn_unused_result|@exported|@lazy|@noescape|@NSCopying|@NSManaged|@objc|@objcMembers|@convention|@required|@noreturn|@IBAction|@IBDesignable|@IBInspectable|@IBOutlet|@infix|@prefix|@postfix|@autoclosure|@testable|@available|@nonobjc|@NSApplicationMain|@UIApplicationMain|@dynamicMemberLookup|@propertyWrapper)\\b"},{beginKeywords:"import",end:/$/,contains:[e.C_LINE_COMMENT_MODE,n]}]}}}()); +hljs.registerLanguage("typescript",function(){"use strict";const e=["as","in","of","if","for","while","finally","var","new","function","do","return","void","else","break","catch","instanceof","with","throw","case","default","try","switch","continue","typeof","delete","let","yield","const","class","debugger","async","await","static","import","from","export","extends"],n=["true","false","null","undefined","NaN","Infinity"],a=[].concat(["setInterval","setTimeout","clearInterval","clearTimeout","require","exports","eval","isFinite","isNaN","parseFloat","parseInt","decodeURI","decodeURIComponent","encodeURI","encodeURIComponent","escape","unescape"],["arguments","this","super","console","window","document","localStorage","module","global"],["Intl","DataView","Number","Math","Date","String","RegExp","Object","Function","Boolean","Error","Symbol","Set","Map","WeakSet","WeakMap","Proxy","Reflect","JSON","Promise","Float64Array","Int16Array","Int32Array","Int8Array","Uint16Array","Uint32Array","Float32Array","Array","Uint8Array","Uint8ClampedArray","ArrayBuffer"],["EvalError","InternalError","RangeError","ReferenceError","SyntaxError","TypeError","URIError"]);return function(r){var t={$pattern:"[A-Za-z$_][0-9A-Za-z$_]*",keyword:e.concat(["type","namespace","typedef","interface","public","private","protected","implements","declare","abstract","readonly"]).join(" "),literal:n.join(" "),built_in:a.concat(["any","void","number","boolean","string","object","never","enum"]).join(" ")},s={className:"meta",begin:"@[A-Za-z$_][0-9A-Za-z$_]*"},i={className:"number",variants:[{begin:"\\b(0[bB][01]+)n?"},{begin:"\\b(0[oO][0-7]+)n?"},{begin:r.C_NUMBER_RE+"n?"}],relevance:0},o={className:"subst",begin:"\\$\\{",end:"\\}",keywords:t,contains:[]},c={begin:"html`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"xml"}},l={begin:"css`",end:"",starts:{end:"`",returnEnd:!1,contains:[r.BACKSLASH_ESCAPE,o],subLanguage:"css"}},E={className:"string",begin:"`",end:"`",contains:[r.BACKSLASH_ESCAPE,o]};o.contains=[r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,i,r.REGEXP_MODE];var d={begin:"\\(",end:/\)/,keywords:t,contains:["self",r.QUOTE_STRING_MODE,r.APOS_STRING_MODE,r.NUMBER_MODE]},u={className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,s,d]};return{name:"TypeScript",aliases:["ts"],keywords:t,contains:[r.SHEBANG(),{className:"meta",begin:/^\s*['"]use strict['"]/},r.APOS_STRING_MODE,r.QUOTE_STRING_MODE,c,l,E,r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,i,{begin:"("+r.RE_STARTERS_RE+"|\\b(case|return|throw)\\b)\\s*",keywords:"return throw case",contains:[r.C_LINE_COMMENT_MODE,r.C_BLOCK_COMMENT_MODE,r.REGEXP_MODE,{className:"function",begin:"(\\([^(]*(\\([^(]*(\\([^(]*\\))?\\))?\\)|"+r.UNDERSCORE_IDENT_RE+")\\s*=>",returnBegin:!0,end:"\\s*=>",contains:[{className:"params",variants:[{begin:r.UNDERSCORE_IDENT_RE},{className:null,begin:/\(\s*\)/,skip:!0},{begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,keywords:t,contains:d.contains}]}]}],relevance:0},{className:"function",beginKeywords:"function",end:/[\{;]/,excludeEnd:!0,keywords:t,contains:["self",r.inherit(r.TITLE_MODE,{begin:"[A-Za-z$_][0-9A-Za-z$_]*"}),u],illegal:/%/,relevance:0},{beginKeywords:"constructor",end:/[\{;]/,excludeEnd:!0,contains:["self",u]},{begin:/module\./,keywords:{built_in:"module"},relevance:0},{beginKeywords:"module",end:/\{/,excludeEnd:!0},{beginKeywords:"interface",end:/\{/,excludeEnd:!0,keywords:"interface extends"},{begin:/\$[(.]/},{begin:"\\."+r.IDENT_RE,relevance:0},s,d]}}}()); +hljs.registerLanguage("yaml",function(){"use strict";return function(e){var n="true false yes no null",a="[\\w#;/?:@&=+$,.~*\\'()[\\]]+",s={className:"string",relevance:0,variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/\S+/}],contains:[e.BACKSLASH_ESCAPE,{className:"template-variable",variants:[{begin:"{{",end:"}}"},{begin:"%{",end:"}"}]}]},i=e.inherit(s,{variants:[{begin:/'/,end:/'/},{begin:/"/,end:/"/},{begin:/[^\s,{}[\]]+/}]}),l={end:",",endsWithParent:!0,excludeEnd:!0,contains:[],keywords:n,relevance:0},t={begin:"{",end:"}",contains:[l],illegal:"\\n",relevance:0},g={begin:"\\[",end:"\\]",contains:[l],illegal:"\\n",relevance:0},b=[{className:"attr",variants:[{begin:"\\w[\\w :\\/.-]*:(?=[ \t]|$)"},{begin:'"\\w[\\w :\\/.-]*":(?=[ \t]|$)'},{begin:"'\\w[\\w :\\/.-]*':(?=[ \t]|$)"}]},{className:"meta",begin:"^---s*$",relevance:10},{className:"string",begin:"[\\|>]([0-9]?[+-])?[ ]*\\n( *)[\\S ]+\\n(\\2[\\S ]+\\n?)*"},{begin:"<%[%=-]?",end:"[%-]?%>",subLanguage:"ruby",excludeBegin:!0,excludeEnd:!0,relevance:0},{className:"type",begin:"!\\w+!"+a},{className:"type",begin:"!<"+a+">"},{className:"type",begin:"!"+a},{className:"type",begin:"!!"+a},{className:"meta",begin:"&"+e.UNDERSCORE_IDENT_RE+"$"},{className:"meta",begin:"\\*"+e.UNDERSCORE_IDENT_RE+"$"},{className:"bullet",begin:"\\-(?=[ ]|$)",relevance:0},e.HASH_COMMENT_MODE,{beginKeywords:n,keywords:{literal:n}},{className:"number",begin:"\\b[0-9]{4}(-[0-9][0-9]){0,2}([Tt \\t][0-9][0-9]?(:[0-9][0-9]){2})?(\\.[0-9]*)?([ \\t])*(Z|[-+][0-9][0-9]?(:[0-9][0-9])?)?\\b"},{className:"number",begin:e.C_NUMBER_RE+"\\b"},t,g,s],c=[...b];return c.pop(),c.push(i),l.contains=c,{name:"YAML",case_insensitive:!0,aliases:["yml","YAML"],contains:b}}}()); +hljs.registerLanguage("armasm",function(){"use strict";return function(s){const e={variants:[s.COMMENT("^[ \\t]*(?=#)","$",{relevance:0,excludeBegin:!0}),s.COMMENT("[;@]","$",{relevance:0}),s.C_LINE_COMMENT_MODE,s.C_BLOCK_COMMENT_MODE]};return{name:"ARM Assembly",case_insensitive:!0,aliases:["arm"],keywords:{$pattern:"\\.?"+s.IDENT_RE,meta:".2byte .4byte .align .ascii .asciz .balign .byte .code .data .else .end .endif .endm .endr .equ .err .exitm .extern .global .hword .if .ifdef .ifndef .include .irp .long .macro .rept .req .section .set .skip .space .text .word .arm .thumb .code16 .code32 .force_thumb .thumb_func .ltorg ALIAS ALIGN ARM AREA ASSERT ATTR CN CODE CODE16 CODE32 COMMON CP DATA DCB DCD DCDU DCDO DCFD DCFDU DCI DCQ DCQU DCW DCWU DN ELIF ELSE END ENDFUNC ENDIF ENDP ENTRY EQU EXPORT EXPORTAS EXTERN FIELD FILL FUNCTION GBLA GBLL GBLS GET GLOBAL IF IMPORT INCBIN INCLUDE INFO KEEP LCLA LCLL LCLS LTORG MACRO MAP MEND MEXIT NOFP OPT PRESERVE8 PROC QN READONLY RELOC REQUIRE REQUIRE8 RLIST FN ROUT SETA SETL SETS SN SPACE SUBT THUMB THUMBX TTL WHILE WEND ",built_in:"r0 r1 r2 r3 r4 r5 r6 r7 r8 r9 r10 r11 r12 r13 r14 r15 pc lr sp ip sl sb fp a1 a2 a3 a4 v1 v2 v3 v4 v5 v6 v7 v8 f0 f1 f2 f3 f4 f5 f6 f7 p0 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 p11 p12 p13 p14 p15 c0 c1 c2 c3 c4 c5 c6 c7 c8 c9 c10 c11 c12 c13 c14 c15 q0 q1 q2 q3 q4 q5 q6 q7 q8 q9 q10 q11 q12 q13 q14 q15 cpsr_c cpsr_x cpsr_s cpsr_f cpsr_cx cpsr_cxs cpsr_xs cpsr_xsf cpsr_sf cpsr_cxsf spsr_c spsr_x spsr_s spsr_f spsr_cx spsr_cxs spsr_xs spsr_xsf spsr_sf spsr_cxsf s0 s1 s2 s3 s4 s5 s6 s7 s8 s9 s10 s11 s12 s13 s14 s15 s16 s17 s18 s19 s20 s21 s22 s23 s24 s25 s26 s27 s28 s29 s30 s31 d0 d1 d2 d3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19 d20 d21 d22 d23 d24 d25 d26 d27 d28 d29 d30 d31 {PC} {VAR} {TRUE} {FALSE} {OPT} {CONFIG} {ENDIAN} {CODESIZE} {CPU} {FPU} {ARCHITECTURE} {PCSTOREOFFSET} {ARMASM_VERSION} {INTER} {ROPI} {RWPI} {SWST} {NOSWST} . @"},contains:[{className:"keyword",begin:"\\b(adc|(qd?|sh?|u[qh]?)?add(8|16)?|usada?8|(q|sh?|u[qh]?)?(as|sa)x|and|adrl?|sbc|rs[bc]|asr|b[lx]?|blx|bxj|cbn?z|tb[bh]|bic|bfc|bfi|[su]bfx|bkpt|cdp2?|clz|clrex|cmp|cmn|cpsi[ed]|cps|setend|dbg|dmb|dsb|eor|isb|it[te]{0,3}|lsl|lsr|ror|rrx|ldm(([id][ab])|f[ds])?|ldr((s|ex)?[bhd])?|movt?|mvn|mra|mar|mul|[us]mull|smul[bwt][bt]|smu[as]d|smmul|smmla|mla|umlaal|smlal?([wbt][bt]|d)|mls|smlsl?[ds]|smc|svc|sev|mia([bt]{2}|ph)?|mrr?c2?|mcrr2?|mrs|msr|orr|orn|pkh(tb|bt)|rbit|rev(16|sh)?|sel|[su]sat(16)?|nop|pop|push|rfe([id][ab])?|stm([id][ab])?|str(ex)?[bhd]?|(qd?)?sub|(sh?|q|u[qh]?)?sub(8|16)|[su]xt(a?h|a?b(16)?)|srs([id][ab])?|swpb?|swi|smi|tst|teq|wfe|wfi|yield)(eq|ne|cs|cc|mi|pl|vs|vc|hi|ls|ge|lt|gt|le|al|hs|lo)?[sptrx]?(?=\\s)"},e,s.QUOTE_STRING_MODE,{className:"string",begin:"'",end:"[^\\\\]'",relevance:0},{className:"title",begin:"\\|",end:"\\|",illegal:"\\n",relevance:0},{className:"number",variants:[{begin:"[#$=]?0x[0-9a-f]+"},{begin:"[#$=]?0b[01]+"},{begin:"[#$=]\\d+"},{begin:"\\b\\d+"}],relevance:0},{className:"symbol",variants:[{begin:"^[ \\t]*[a-z_\\.\\$][a-z0-9_\\.\\$]+:"},{begin:"^[a-z_\\.\\$][a-z0-9_\\.\\$]+"},{begin:"[=#]\\w+"}],relevance:0}]}}}()); +hljs.registerLanguage("d",function(){"use strict";return function(e){var a={$pattern:e.UNDERSCORE_IDENT_RE,keyword:"abstract alias align asm assert auto body break byte case cast catch class const continue debug default delete deprecated do else enum export extern final finally for foreach foreach_reverse|10 goto if immutable import in inout int interface invariant is lazy macro mixin module new nothrow out override package pragma private protected public pure ref return scope shared static struct super switch synchronized template this throw try typedef typeid typeof union unittest version void volatile while with __FILE__ __LINE__ __gshared|10 __thread __traits __DATE__ __EOF__ __TIME__ __TIMESTAMP__ __VENDOR__ __VERSION__",built_in:"bool cdouble cent cfloat char creal dchar delegate double dstring float function idouble ifloat ireal long real short string ubyte ucent uint ulong ushort wchar wstring",literal:"false null true"},d="((0|[1-9][\\d_]*)|0[bB][01_]+|0[xX]([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))",n="\\\\(['\"\\?\\\\abfnrtv]|u[\\dA-Fa-f]{4}|[0-7]{1,3}|x[\\dA-Fa-f]{2}|U[\\dA-Fa-f]{8})|&[a-zA-Z\\d]{2,};",t={className:"number",begin:"\\b"+d+"(L|u|U|Lu|LU|uL|UL)?",relevance:0},_={className:"number",begin:"\\b(((0[xX](([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)\\.([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*)|\\.?([\\da-fA-F][\\da-fA-F_]*|_[\\da-fA-F][\\da-fA-F_]*))[pP][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))|((0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(\\.\\d*|([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)))|\\d+\\.(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d)|\\.(0|[1-9][\\d_]*)([eE][+-]?(0|[1-9][\\d_]*|\\d[\\d_]*|[\\d_]+?\\d))?))([fF]|L|i|[fF]i|Li)?|"+d+"(i|[fF]i|Li))",relevance:0},r={className:"string",begin:"'("+n+"|.)",end:"'",illegal:"."},i={className:"string",begin:'"',contains:[{begin:n,relevance:0}],end:'"[cwd]?'},s=e.COMMENT("\\/\\+","\\+\\/",{contains:["self"],relevance:10});return{name:"D",keywords:a,contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,s,{className:"string",begin:'x"[\\da-fA-F\\s\\n\\r]*"[cwd]?',relevance:10},i,{className:"string",begin:'[rq]"',end:'"[cwd]?',relevance:5},{className:"string",begin:"`",end:"`[cwd]?"},{className:"string",begin:'q"\\{',end:'\\}"'},_,t,r,{className:"meta",begin:"^#!",end:"$",relevance:5},{className:"meta",begin:"#(line)",end:"$",relevance:5},{className:"keyword",begin:"@[a-zA-Z_][a-zA-Z_\\d]*"}]}}}()); +hljs.registerLanguage("handlebars",function(){"use strict";function e(...e){return e.map(e=>(function(e){return e?"string"==typeof e?e:e.source:null})(e)).join("")}return function(n){const a={"builtin-name":"action bindattr collection component concat debugger each each-in get hash if in input link-to loc log lookup mut outlet partial query-params render template textarea unbound unless view with yield"},t=/\[.*?\]/,s=/[^\s!"#%&'()*+,.\/;<=>@\[\\\]^`{|}~]+/,i=e("(",/'.*?'/,"|",/".*?"/,"|",t,"|",s,"|",/\.|\//,")+"),r=e("(",t,"|",s,")(?==)"),l={begin:i,lexemes:/[\w.\/]+/},c=n.inherit(l,{keywords:{literal:"true false undefined null"}}),o={begin:/\(/,end:/\)/},m={className:"attr",begin:r,relevance:0,starts:{begin:/=/,end:/=/,starts:{contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,c,o]}}},d={contains:[n.NUMBER_MODE,n.QUOTE_STRING_MODE,n.APOS_STRING_MODE,{begin:/as\s+\|/,keywords:{keyword:"as"},end:/\|/,contains:[{begin:/\w+/}]},m,c,o],returnEnd:!0},g=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/\)/})});o.contains=[g];const u=n.inherit(l,{keywords:a,className:"name",starts:n.inherit(d,{end:/}}/})}),b=n.inherit(l,{keywords:a,className:"name"}),h=n.inherit(l,{className:"name",keywords:a,starts:n.inherit(d,{end:/}}/})});return{name:"Handlebars",aliases:["hbs","html.hbs","html.handlebars","htmlbars"],case_insensitive:!0,subLanguage:"xml",contains:[{begin:/\\\{\{/,skip:!0},{begin:/\\\\(?=\{\{)/,skip:!0},n.COMMENT(/\{\{!--/,/--\}\}/),n.COMMENT(/\{\{!/,/\}\}/),{className:"template-tag",begin:/\{\{\{\{(?!\/)/,end:/\}\}\}\}/,contains:[u],starts:{end:/\{\{\{\{\//,returnEnd:!0,subLanguage:"xml"}},{className:"template-tag",begin:/\{\{\{\{\//,end:/\}\}\}\}/,contains:[b]},{className:"template-tag",begin:/\{\{#/,end:/\}\}/,contains:[u]},{className:"template-tag",begin:/\{\{(?=else\}\})/,end:/\}\}/,keywords:"else"},{className:"template-tag",begin:/\{\{\//,end:/\}\}/,contains:[b]},{className:"template-variable",begin:/\{\{\{/,end:/\}\}\}/,contains:[h]},{className:"template-variable",begin:/\{\{/,end:/\}\}/,contains:[h]}]}}}()); +hljs.registerLanguage("haskell",function(){"use strict";return function(e){var n={variants:[e.COMMENT("--","$"),e.COMMENT("{-","-}",{contains:["self"]})]},i={className:"meta",begin:"{-#",end:"#-}"},a={className:"meta",begin:"^#",end:"$"},s={className:"type",begin:"\\b[A-Z][\\w']*",relevance:0},l={begin:"\\(",end:"\\)",illegal:'"',contains:[i,a,{className:"type",begin:"\\b[A-Z][\\w]*(\\((\\.\\.|,|\\w+)\\))?"},e.inherit(e.TITLE_MODE,{begin:"[_a-z][\\w']*"}),n]};return{name:"Haskell",aliases:["hs"],keywords:"let in if then else case of where do module import hiding qualified type data newtype deriving class instance as default infix infixl infixr foreign export ccall stdcall cplusplus jvm dotnet safe unsafe family forall mdo proc rec",contains:[{beginKeywords:"module",end:"where",keywords:"module where",contains:[l,n],illegal:"\\W\\.|;"},{begin:"\\bimport\\b",end:"$",keywords:"import qualified as hiding",contains:[l,n],illegal:"\\W\\.|;"},{className:"class",begin:"^(\\s*)?(class|instance)\\b",end:"where",keywords:"class family instance where",contains:[s,l,n]},{className:"class",begin:"\\b(data|(new)?type)\\b",end:"$",keywords:"data family type newtype deriving",contains:[i,s,l,{begin:"{",end:"}",contains:l.contains},n]},{beginKeywords:"default",end:"$",contains:[s,l,n]},{beginKeywords:"infix infixl infixr",end:"$",contains:[e.C_NUMBER_MODE,n]},{begin:"\\bforeign\\b",end:"$",keywords:"foreign import export ccall stdcall cplusplus jvm dotnet safe unsafe",contains:[s,e.QUOTE_STRING_MODE,n]},{className:"meta",begin:"#!\\/usr\\/bin\\/env runhaskell",end:"$"},i,a,e.QUOTE_STRING_MODE,e.C_NUMBER_MODE,s,e.inherit(e.TITLE_MODE,{begin:"^[_a-z][\\w']*"}),n,{begin:"->|<-"}]}}}()); +hljs.registerLanguage("julia",function(){"use strict";return function(e){var r="[A-Za-z_\\u00A1-\\uFFFF][A-Za-z_0-9\\u00A1-\\uFFFF]*",t={$pattern:r,keyword:"in isa where baremodule begin break catch ccall const continue do else elseif end export false finally for function global if import importall let local macro module quote return true try using while type immutable abstract bitstype typealias ",literal:"true false ARGS C_NULL DevNull ENDIAN_BOM ENV I Inf Inf16 Inf32 Inf64 InsertionSort JULIA_HOME LOAD_PATH MergeSort NaN NaN16 NaN32 NaN64 PROGRAM_FILE QuickSort RoundDown RoundFromZero RoundNearest RoundNearestTiesAway RoundNearestTiesUp RoundToZero RoundUp STDERR STDIN STDOUT VERSION catalan e|0 eu|0 eulergamma golden im nothing pi γ π φ ",built_in:"ANY AbstractArray AbstractChannel AbstractFloat AbstractMatrix AbstractRNG AbstractSerializer AbstractSet AbstractSparseArray AbstractSparseMatrix AbstractSparseVector AbstractString AbstractUnitRange AbstractVecOrMat AbstractVector Any ArgumentError Array AssertionError Associative Base64DecodePipe Base64EncodePipe Bidiagonal BigFloat BigInt BitArray BitMatrix BitVector Bool BoundsError BufferStream CachingPool CapturedException CartesianIndex CartesianRange Cchar Cdouble Cfloat Channel Char Cint Cintmax_t Clong Clonglong ClusterManager Cmd CodeInfo Colon Complex Complex128 Complex32 Complex64 CompositeException Condition ConjArray ConjMatrix ConjVector Cptrdiff_t Cshort Csize_t Cssize_t Cstring Cuchar Cuint Cuintmax_t Culong Culonglong Cushort Cwchar_t Cwstring DataType Date DateFormat DateTime DenseArray DenseMatrix DenseVecOrMat DenseVector Diagonal Dict DimensionMismatch Dims DirectIndexString Display DivideError DomainError EOFError EachLine Enum Enumerate ErrorException Exception ExponentialBackOff Expr Factorization FileMonitor Float16 Float32 Float64 Function Future GlobalRef GotoNode HTML Hermitian IO IOBuffer IOContext IOStream IPAddr IPv4 IPv6 IndexCartesian IndexLinear IndexStyle InexactError InitError Int Int128 Int16 Int32 Int64 Int8 IntSet Integer InterruptException InvalidStateException Irrational KeyError LabelNode LinSpace LineNumberNode LoadError LowerTriangular MIME Matrix MersenneTwister Method MethodError MethodTable Module NTuple NewvarNode NullException Nullable Number ObjectIdDict OrdinalRange OutOfMemoryError OverflowError Pair ParseError PartialQuickSort PermutedDimsArray Pipe PollingFileWatcher ProcessExitedException Ptr QuoteNode RandomDevice Range RangeIndex Rational RawFD ReadOnlyMemoryError Real ReentrantLock Ref Regex RegexMatch RemoteChannel RemoteException RevString RoundingMode RowVector SSAValue SegmentationFault SerializationState Set SharedArray SharedMatrix SharedVector Signed SimpleVector Slot SlotNumber SparseMatrixCSC SparseVector StackFrame StackOverflowError StackTrace StepRange StepRangeLen StridedArray StridedMatrix StridedVecOrMat StridedVector String SubArray SubString SymTridiagonal Symbol Symmetric SystemError TCPSocket Task Text TextDisplay Timer Tridiagonal Tuple Type TypeError TypeMapEntry TypeMapLevel TypeName TypeVar TypedSlot UDPSocket UInt UInt128 UInt16 UInt32 UInt64 UInt8 UndefRefError UndefVarError UnicodeError UniformScaling Union UnionAll UnitRange Unsigned UpperTriangular Val Vararg VecElement VecOrMat Vector VersionNumber Void WeakKeyDict WeakRef WorkerConfig WorkerPool "},a={keywords:t,illegal:/<\//},n={className:"subst",begin:/\$\(/,end:/\)/,keywords:t},o={className:"variable",begin:"\\$"+r},i={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],variants:[{begin:/\w*"""/,end:/"""\w*/,relevance:10},{begin:/\w*"/,end:/"\w*/}]},l={className:"string",contains:[e.BACKSLASH_ESCAPE,n,o],begin:"`",end:"`"},s={className:"meta",begin:"@"+r};return a.name="Julia",a.contains=[{className:"number",begin:/(\b0x[\d_]*(\.[\d_]*)?|0x\.\d[\d_]*)p[-+]?\d+|\b0[box][a-fA-F0-9][a-fA-F0-9_]*|(\b\d[\d_]*(\.[\d_]*)?|\.\d[\d_]*)([eEfF][-+]?\d+)?/,relevance:0},{className:"string",begin:/'(.|\\[xXuU][a-zA-Z0-9]+)'/},i,l,s,{className:"comment",variants:[{begin:"#=",end:"=#",relevance:10},{begin:"#",end:"$"}]},e.HASH_COMMENT_MODE,{className:"keyword",begin:"\\b(((abstract|primitive)\\s+)type|(mutable\\s+)?struct)\\b"},{begin:/<:/}],n.contains=a.contains,a}}()); +hljs.registerLanguage("nim",function(){"use strict";return function(e){return{name:"Nim",aliases:["nim"],keywords:{keyword:"addr and as asm bind block break case cast const continue converter discard distinct div do elif else end enum except export finally for from func generic if import in include interface is isnot iterator let macro method mixin mod nil not notin object of or out proc ptr raise ref return shl shr static template try tuple type using var when while with without xor yield",literal:"shared guarded stdin stdout stderr result true false",built_in:"int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 float float32 float64 bool char string cstring pointer expr stmt void auto any range array openarray varargs seq set clong culong cchar cschar cshort cint csize clonglong cfloat cdouble clongdouble cuchar cushort cuint culonglong cstringarray semistatic"},contains:[{className:"meta",begin:/{\./,end:/\.}/,relevance:10},{className:"string",begin:/[a-zA-Z]\w*"/,end:/"/,contains:[{begin:/""/}]},{className:"string",begin:/([a-zA-Z]\w*)?"""/,end:/"""/},e.QUOTE_STRING_MODE,{className:"type",begin:/\b[A-Z]\w+\b/,relevance:0},{className:"number",relevance:0,variants:[{begin:/\b(0[xX][0-9a-fA-F][_0-9a-fA-F]*)('?[iIuU](8|16|32|64))?/},{begin:/\b(0o[0-7][_0-7]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\b(0(b|B)[01][_01]*)('?[iIuUfF](8|16|32|64))?/},{begin:/\b(\d[_\d]*)('?[iIuUfF](8|16|32|64))?/}]},e.HASH_COMMENT_MODE]}}}()); +hljs.registerLanguage("nix",function(){"use strict";return function(e){var n={keyword:"rec with let in inherit assert if else then",literal:"true false or and null",built_in:"import abort baseNameOf dirOf isNull builtins map removeAttrs throw toString derivation"},i={className:"subst",begin:/\$\{/,end:/}/,keywords:n},t={className:"string",contains:[i],variants:[{begin:"''",end:"''"},{begin:'"',end:'"'}]},s=[e.NUMBER_MODE,e.HASH_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,t,{begin:/[a-zA-Z0-9-_]+(\s*=)/,returnBegin:!0,relevance:0,contains:[{className:"attr",begin:/\S+/}]}];return i.contains=s,{name:"Nix",aliases:["nixos"],keywords:n,contains:s}}}()); +hljs.registerLanguage("r",function(){"use strict";return function(e){var n="([a-zA-Z]|\\.[a-zA-Z.])[a-zA-Z0-9._]*";return{name:"R",contains:[e.HASH_COMMENT_MODE,{begin:n,keywords:{$pattern:n,keyword:"function if in break next repeat else for return switch while try tryCatch stop warning require library attach detach source setMethod setGeneric setGroupGeneric setClass ...",literal:"NULL NA TRUE FALSE T F Inf NaN NA_integer_|10 NA_real_|10 NA_character_|10 NA_complex_|10"},relevance:0},{className:"number",begin:"0[xX][0-9a-fA-F]+[Li]?\\b",relevance:0},{className:"number",begin:"\\d+(?:[eE][+\\-]?\\d*)?L\\b",relevance:0},{className:"number",begin:"\\d+\\.(?!\\d)(?:i\\b)?",relevance:0},{className:"number",begin:"\\d+(?:\\.\\d*)?(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{className:"number",begin:"\\.\\d+(?:[eE][+\\-]?\\d*)?i?\\b",relevance:0},{begin:"`",end:"`",relevance:0},{className:"string",contains:[e.BACKSLASH_ESCAPE],variants:[{begin:'"',end:'"'},{begin:"'",end:"'"}]}]}}}()); +hljs.registerLanguage("scala",function(){"use strict";return function(e){var n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"},{begin:"\\${",end:"}"}]},a={className:"string",variants:[{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE]},{begin:'"""',end:'"""',relevance:10},{begin:'[a-z]+"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n]},{className:"string",begin:'[a-z]+"""',end:'"""',contains:[n],relevance:10}]},s={className:"type",begin:"\\b[A-Z][A-Za-z0-9_]*",relevance:0},t={className:"title",begin:/[^0-9\n\t "'(),.`{}\[\]:;][^\n\t "'(),.`{}\[\]:;]+|[^0-9\n\t "'(),.`{}\[\]:;=]/,relevance:0},i={className:"class",beginKeywords:"class object trait type",end:/[:={\[\n;]/,excludeEnd:!0,contains:[{beginKeywords:"extends with",relevance:10},{begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},{className:"params",begin:/\(/,end:/\)/,excludeBegin:!0,excludeEnd:!0,relevance:0,contains:[s]},t]},l={className:"function",beginKeywords:"def",end:/[:={\[(\n;]/,excludeEnd:!0,contains:[t]};return{name:"Scala",keywords:{literal:"true false null",keyword:"type yield lazy override def with val var sealed abstract private trait object if forSome for while throw finally protected extends import final return else break new catch super class case package default try this match continue throws implicit"},contains:[e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,a,{className:"symbol",begin:"'\\w[\\w\\d_]*(?!')"},s,l,i,e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"}]}}}()); +hljs.registerLanguage("x86asm",function(){"use strict";return function(s){return{name:"Intel x86 Assembly",case_insensitive:!0,keywords:{$pattern:"[.%]?"+s.IDENT_RE,keyword:"lock rep repe repz repne repnz xaquire xrelease bnd nobnd aaa aad aam aas adc add and arpl bb0_reset bb1_reset bound bsf bsr bswap bt btc btr bts call cbw cdq cdqe clc cld cli clts cmc cmp cmpsb cmpsd cmpsq cmpsw cmpxchg cmpxchg486 cmpxchg8b cmpxchg16b cpuid cpu_read cpu_write cqo cwd cwde daa das dec div dmint emms enter equ f2xm1 fabs fadd faddp fbld fbstp fchs fclex fcmovb fcmovbe fcmove fcmovnb fcmovnbe fcmovne fcmovnu fcmovu fcom fcomi fcomip fcomp fcompp fcos fdecstp fdisi fdiv fdivp fdivr fdivrp femms feni ffree ffreep fiadd ficom ficomp fidiv fidivr fild fimul fincstp finit fist fistp fisttp fisub fisubr fld fld1 fldcw fldenv fldl2e fldl2t fldlg2 fldln2 fldpi fldz fmul fmulp fnclex fndisi fneni fninit fnop fnsave fnstcw fnstenv fnstsw fpatan fprem fprem1 fptan frndint frstor fsave fscale fsetpm fsin fsincos fsqrt fst fstcw fstenv fstp fstsw fsub fsubp fsubr fsubrp ftst fucom fucomi fucomip fucomp fucompp fxam fxch fxtract fyl2x fyl2xp1 hlt ibts icebp idiv imul in inc incbin insb insd insw int int01 int1 int03 int3 into invd invpcid invlpg invlpga iret iretd iretq iretw jcxz jecxz jrcxz jmp jmpe lahf lar lds lea leave les lfence lfs lgdt lgs lidt lldt lmsw loadall loadall286 lodsb lodsd lodsq lodsw loop loope loopne loopnz loopz lsl lss ltr mfence monitor mov movd movq movsb movsd movsq movsw movsx movsxd movzx mul mwait neg nop not or out outsb outsd outsw packssdw packsswb packuswb paddb paddd paddsb paddsiw paddsw paddusb paddusw paddw pand pandn pause paveb pavgusb pcmpeqb pcmpeqd pcmpeqw pcmpgtb pcmpgtd pcmpgtw pdistib pf2id pfacc pfadd pfcmpeq pfcmpge pfcmpgt pfmax pfmin pfmul pfrcp pfrcpit1 pfrcpit2 pfrsqit1 pfrsqrt pfsub pfsubr pi2fd pmachriw pmaddwd pmagw pmulhriw pmulhrwa pmulhrwc pmulhw pmullw pmvgezb pmvlzb pmvnzb pmvzb pop popa popad popaw popf popfd popfq popfw por prefetch prefetchw pslld psllq psllw psrad psraw psrld psrlq psrlw psubb psubd psubsb psubsiw psubsw psubusb psubusw psubw punpckhbw punpckhdq punpckhwd punpcklbw punpckldq punpcklwd push pusha pushad pushaw pushf pushfd pushfq pushfw pxor rcl rcr rdshr rdmsr rdpmc rdtsc rdtscp ret retf retn rol ror rdm rsdc rsldt rsm rsts sahf sal salc sar sbb scasb scasd scasq scasw sfence sgdt shl shld shr shrd sidt sldt skinit smi smint smintold smsw stc std sti stosb stosd stosq stosw str sub svdc svldt svts swapgs syscall sysenter sysexit sysret test ud0 ud1 ud2b ud2 ud2a umov verr verw fwait wbinvd wrshr wrmsr xadd xbts xchg xlatb xlat xor cmove cmovz cmovne cmovnz cmova cmovnbe cmovae cmovnb cmovb cmovnae cmovbe cmovna cmovg cmovnle cmovge cmovnl cmovl cmovnge cmovle cmovng cmovc cmovnc cmovo cmovno cmovs cmovns cmovp cmovpe cmovnp cmovpo je jz jne jnz ja jnbe jae jnb jb jnae jbe jna jg jnle jge jnl jl jnge jle jng jc jnc jo jno js jns jpo jnp jpe jp sete setz setne setnz seta setnbe setae setnb setnc setb setnae setcset setbe setna setg setnle setge setnl setl setnge setle setng sets setns seto setno setpe setp setpo setnp addps addss andnps andps cmpeqps cmpeqss cmpleps cmpless cmpltps cmpltss cmpneqps cmpneqss cmpnleps cmpnless cmpnltps cmpnltss cmpordps cmpordss cmpunordps cmpunordss cmpps cmpss comiss cvtpi2ps cvtps2pi cvtsi2ss cvtss2si cvttps2pi cvttss2si divps divss ldmxcsr maxps maxss minps minss movaps movhps movlhps movlps movhlps movmskps movntps movss movups mulps mulss orps rcpps rcpss rsqrtps rsqrtss shufps sqrtps sqrtss stmxcsr subps subss ucomiss unpckhps unpcklps xorps fxrstor fxrstor64 fxsave fxsave64 xgetbv xsetbv xsave xsave64 xsaveopt xsaveopt64 xrstor xrstor64 prefetchnta prefetcht0 prefetcht1 prefetcht2 maskmovq movntq pavgb pavgw pextrw pinsrw pmaxsw pmaxub pminsw pminub pmovmskb pmulhuw psadbw pshufw pf2iw pfnacc pfpnacc pi2fw pswapd maskmovdqu clflush movntdq movnti movntpd movdqa movdqu movdq2q movq2dq paddq pmuludq pshufd pshufhw pshuflw pslldq psrldq psubq punpckhqdq punpcklqdq addpd addsd andnpd andpd cmpeqpd cmpeqsd cmplepd cmplesd cmpltpd cmpltsd cmpneqpd cmpneqsd cmpnlepd cmpnlesd cmpnltpd cmpnltsd cmpordpd cmpordsd cmpunordpd cmpunordsd cmppd comisd cvtdq2pd cvtdq2ps cvtpd2dq cvtpd2pi cvtpd2ps cvtpi2pd cvtps2dq cvtps2pd cvtsd2si cvtsd2ss cvtsi2sd cvtss2sd cvttpd2pi cvttpd2dq cvttps2dq cvttsd2si divpd divsd maxpd maxsd minpd minsd movapd movhpd movlpd movmskpd movupd mulpd mulsd orpd shufpd sqrtpd sqrtsd subpd subsd ucomisd unpckhpd unpcklpd xorpd addsubpd addsubps haddpd haddps hsubpd hsubps lddqu movddup movshdup movsldup clgi stgi vmcall vmclear vmfunc vmlaunch vmload vmmcall vmptrld vmptrst vmread vmresume vmrun vmsave vmwrite vmxoff vmxon invept invvpid pabsb pabsw pabsd palignr phaddw phaddd phaddsw phsubw phsubd phsubsw pmaddubsw pmulhrsw pshufb psignb psignw psignd extrq insertq movntsd movntss lzcnt blendpd blendps blendvpd blendvps dppd dpps extractps insertps movntdqa mpsadbw packusdw pblendvb pblendw pcmpeqq pextrb pextrd pextrq phminposuw pinsrb pinsrd pinsrq pmaxsb pmaxsd pmaxud pmaxuw pminsb pminsd pminud pminuw pmovsxbw pmovsxbd pmovsxbq pmovsxwd pmovsxwq pmovsxdq pmovzxbw pmovzxbd pmovzxbq pmovzxwd pmovzxwq pmovzxdq pmuldq pmulld ptest roundpd roundps roundsd roundss crc32 pcmpestri pcmpestrm pcmpistri pcmpistrm pcmpgtq popcnt getsec pfrcpv pfrsqrtv movbe aesenc aesenclast aesdec aesdeclast aesimc aeskeygenassist vaesenc vaesenclast vaesdec vaesdeclast vaesimc vaeskeygenassist vaddpd vaddps vaddsd vaddss vaddsubpd vaddsubps vandpd vandps vandnpd vandnps vblendpd vblendps vblendvpd vblendvps vbroadcastss vbroadcastsd vbroadcastf128 vcmpeq_ospd vcmpeqpd vcmplt_ospd vcmpltpd vcmple_ospd vcmplepd vcmpunord_qpd vcmpunordpd vcmpneq_uqpd vcmpneqpd vcmpnlt_uspd vcmpnltpd vcmpnle_uspd vcmpnlepd vcmpord_qpd vcmpordpd vcmpeq_uqpd vcmpnge_uspd vcmpngepd vcmpngt_uspd vcmpngtpd vcmpfalse_oqpd vcmpfalsepd vcmpneq_oqpd vcmpge_ospd vcmpgepd vcmpgt_ospd vcmpgtpd vcmptrue_uqpd vcmptruepd vcmplt_oqpd vcmple_oqpd vcmpunord_spd vcmpneq_uspd vcmpnlt_uqpd vcmpnle_uqpd vcmpord_spd vcmpeq_uspd vcmpnge_uqpd vcmpngt_uqpd vcmpfalse_ospd vcmpneq_ospd vcmpge_oqpd vcmpgt_oqpd vcmptrue_uspd vcmppd vcmpeq_osps vcmpeqps vcmplt_osps vcmpltps vcmple_osps vcmpleps vcmpunord_qps vcmpunordps vcmpneq_uqps vcmpneqps vcmpnlt_usps vcmpnltps vcmpnle_usps vcmpnleps vcmpord_qps vcmpordps vcmpeq_uqps vcmpnge_usps vcmpngeps vcmpngt_usps vcmpngtps vcmpfalse_oqps vcmpfalseps vcmpneq_oqps vcmpge_osps vcmpgeps vcmpgt_osps vcmpgtps vcmptrue_uqps vcmptrueps vcmplt_oqps vcmple_oqps vcmpunord_sps vcmpneq_usps vcmpnlt_uqps vcmpnle_uqps vcmpord_sps vcmpeq_usps vcmpnge_uqps vcmpngt_uqps vcmpfalse_osps vcmpneq_osps vcmpge_oqps vcmpgt_oqps vcmptrue_usps vcmpps vcmpeq_ossd vcmpeqsd vcmplt_ossd vcmpltsd vcmple_ossd vcmplesd vcmpunord_qsd vcmpunordsd vcmpneq_uqsd vcmpneqsd vcmpnlt_ussd vcmpnltsd vcmpnle_ussd vcmpnlesd vcmpord_qsd vcmpordsd vcmpeq_uqsd vcmpnge_ussd vcmpngesd vcmpngt_ussd vcmpngtsd vcmpfalse_oqsd vcmpfalsesd vcmpneq_oqsd vcmpge_ossd vcmpgesd vcmpgt_ossd vcmpgtsd vcmptrue_uqsd vcmptruesd vcmplt_oqsd vcmple_oqsd vcmpunord_ssd vcmpneq_ussd vcmpnlt_uqsd vcmpnle_uqsd vcmpord_ssd vcmpeq_ussd vcmpnge_uqsd vcmpngt_uqsd vcmpfalse_ossd vcmpneq_ossd vcmpge_oqsd vcmpgt_oqsd vcmptrue_ussd vcmpsd vcmpeq_osss vcmpeqss vcmplt_osss vcmpltss vcmple_osss vcmpless vcmpunord_qss vcmpunordss vcmpneq_uqss vcmpneqss vcmpnlt_usss vcmpnltss vcmpnle_usss vcmpnless vcmpord_qss vcmpordss vcmpeq_uqss vcmpnge_usss vcmpngess vcmpngt_usss vcmpngtss vcmpfalse_oqss vcmpfalsess vcmpneq_oqss vcmpge_osss vcmpgess vcmpgt_osss vcmpgtss vcmptrue_uqss vcmptruess vcmplt_oqss vcmple_oqss vcmpunord_sss vcmpneq_usss vcmpnlt_uqss vcmpnle_uqss vcmpord_sss vcmpeq_usss vcmpnge_uqss vcmpngt_uqss vcmpfalse_osss vcmpneq_osss vcmpge_oqss vcmpgt_oqss vcmptrue_usss vcmpss vcomisd vcomiss vcvtdq2pd vcvtdq2ps vcvtpd2dq vcvtpd2ps vcvtps2dq vcvtps2pd vcvtsd2si vcvtsd2ss vcvtsi2sd vcvtsi2ss vcvtss2sd vcvtss2si vcvttpd2dq vcvttps2dq vcvttsd2si vcvttss2si vdivpd vdivps vdivsd vdivss vdppd vdpps vextractf128 vextractps vhaddpd vhaddps vhsubpd vhsubps vinsertf128 vinsertps vlddqu vldqqu vldmxcsr vmaskmovdqu vmaskmovps vmaskmovpd vmaxpd vmaxps vmaxsd vmaxss vminpd vminps vminsd vminss vmovapd vmovaps vmovd vmovq vmovddup vmovdqa vmovqqa vmovdqu vmovqqu vmovhlps vmovhpd vmovhps vmovlhps vmovlpd vmovlps vmovmskpd vmovmskps vmovntdq vmovntqq vmovntdqa vmovntpd vmovntps vmovsd vmovshdup vmovsldup vmovss vmovupd vmovups vmpsadbw vmulpd vmulps vmulsd vmulss vorpd vorps vpabsb vpabsw vpabsd vpacksswb vpackssdw vpackuswb vpackusdw vpaddb vpaddw vpaddd vpaddq vpaddsb vpaddsw vpaddusb vpaddusw vpalignr vpand vpandn vpavgb vpavgw vpblendvb vpblendw vpcmpestri vpcmpestrm vpcmpistri vpcmpistrm vpcmpeqb vpcmpeqw vpcmpeqd vpcmpeqq vpcmpgtb vpcmpgtw vpcmpgtd vpcmpgtq vpermilpd vpermilps vperm2f128 vpextrb vpextrw vpextrd vpextrq vphaddw vphaddd vphaddsw vphminposuw vphsubw vphsubd vphsubsw vpinsrb vpinsrw vpinsrd vpinsrq vpmaddwd vpmaddubsw vpmaxsb vpmaxsw vpmaxsd vpmaxub vpmaxuw vpmaxud vpminsb vpminsw vpminsd vpminub vpminuw vpminud vpmovmskb vpmovsxbw vpmovsxbd vpmovsxbq vpmovsxwd vpmovsxwq vpmovsxdq vpmovzxbw vpmovzxbd vpmovzxbq vpmovzxwd vpmovzxwq vpmovzxdq vpmulhuw vpmulhrsw vpmulhw vpmullw vpmulld vpmuludq vpmuldq vpor vpsadbw vpshufb vpshufd vpshufhw vpshuflw vpsignb vpsignw vpsignd vpslldq vpsrldq vpsllw vpslld vpsllq vpsraw vpsrad vpsrlw vpsrld vpsrlq vptest vpsubb vpsubw vpsubd vpsubq vpsubsb vpsubsw vpsubusb vpsubusw vpunpckhbw vpunpckhwd vpunpckhdq vpunpckhqdq vpunpcklbw vpunpcklwd vpunpckldq vpunpcklqdq vpxor vrcpps vrcpss vrsqrtps vrsqrtss vroundpd vroundps vroundsd vroundss vshufpd vshufps vsqrtpd vsqrtps vsqrtsd vsqrtss vstmxcsr vsubpd vsubps vsubsd vsubss vtestps vtestpd vucomisd vucomiss vunpckhpd vunpckhps vunpcklpd vunpcklps vxorpd vxorps vzeroall vzeroupper pclmullqlqdq pclmulhqlqdq pclmullqhqdq pclmulhqhqdq pclmulqdq vpclmullqlqdq vpclmulhqlqdq vpclmullqhqdq vpclmulhqhqdq vpclmulqdq vfmadd132ps vfmadd132pd vfmadd312ps vfmadd312pd vfmadd213ps vfmadd213pd vfmadd123ps vfmadd123pd vfmadd231ps vfmadd231pd vfmadd321ps vfmadd321pd vfmaddsub132ps vfmaddsub132pd vfmaddsub312ps vfmaddsub312pd vfmaddsub213ps vfmaddsub213pd vfmaddsub123ps vfmaddsub123pd vfmaddsub231ps vfmaddsub231pd vfmaddsub321ps vfmaddsub321pd vfmsub132ps vfmsub132pd vfmsub312ps vfmsub312pd vfmsub213ps vfmsub213pd vfmsub123ps vfmsub123pd vfmsub231ps vfmsub231pd vfmsub321ps vfmsub321pd vfmsubadd132ps vfmsubadd132pd vfmsubadd312ps vfmsubadd312pd vfmsubadd213ps vfmsubadd213pd vfmsubadd123ps vfmsubadd123pd vfmsubadd231ps vfmsubadd231pd vfmsubadd321ps vfmsubadd321pd vfnmadd132ps vfnmadd132pd vfnmadd312ps vfnmadd312pd vfnmadd213ps vfnmadd213pd vfnmadd123ps vfnmadd123pd vfnmadd231ps vfnmadd231pd vfnmadd321ps vfnmadd321pd vfnmsub132ps vfnmsub132pd vfnmsub312ps vfnmsub312pd vfnmsub213ps vfnmsub213pd vfnmsub123ps vfnmsub123pd vfnmsub231ps vfnmsub231pd vfnmsub321ps vfnmsub321pd vfmadd132ss vfmadd132sd vfmadd312ss vfmadd312sd vfmadd213ss vfmadd213sd vfmadd123ss vfmadd123sd vfmadd231ss vfmadd231sd vfmadd321ss vfmadd321sd vfmsub132ss vfmsub132sd vfmsub312ss vfmsub312sd vfmsub213ss vfmsub213sd vfmsub123ss vfmsub123sd vfmsub231ss vfmsub231sd vfmsub321ss vfmsub321sd vfnmadd132ss vfnmadd132sd vfnmadd312ss vfnmadd312sd vfnmadd213ss vfnmadd213sd vfnmadd123ss vfnmadd123sd vfnmadd231ss vfnmadd231sd vfnmadd321ss vfnmadd321sd vfnmsub132ss vfnmsub132sd vfnmsub312ss vfnmsub312sd vfnmsub213ss vfnmsub213sd vfnmsub123ss vfnmsub123sd vfnmsub231ss vfnmsub231sd vfnmsub321ss vfnmsub321sd rdfsbase rdgsbase rdrand wrfsbase wrgsbase vcvtph2ps vcvtps2ph adcx adox rdseed clac stac xstore xcryptecb xcryptcbc xcryptctr xcryptcfb xcryptofb montmul xsha1 xsha256 llwpcb slwpcb lwpval lwpins vfmaddpd vfmaddps vfmaddsd vfmaddss vfmaddsubpd vfmaddsubps vfmsubaddpd vfmsubaddps vfmsubpd vfmsubps vfmsubsd vfmsubss vfnmaddpd vfnmaddps vfnmaddsd vfnmaddss vfnmsubpd vfnmsubps vfnmsubsd vfnmsubss vfrczpd vfrczps vfrczsd vfrczss vpcmov vpcomb vpcomd vpcomq vpcomub vpcomud vpcomuq vpcomuw vpcomw vphaddbd vphaddbq vphaddbw vphadddq vphaddubd vphaddubq vphaddubw vphaddudq vphadduwd vphadduwq vphaddwd vphaddwq vphsubbw vphsubdq vphsubwd vpmacsdd vpmacsdqh vpmacsdql vpmacssdd vpmacssdqh vpmacssdql vpmacsswd vpmacssww vpmacswd vpmacsww vpmadcsswd vpmadcswd vpperm vprotb vprotd vprotq vprotw vpshab vpshad vpshaq vpshaw vpshlb vpshld vpshlq vpshlw vbroadcasti128 vpblendd vpbroadcastb vpbroadcastw vpbroadcastd vpbroadcastq vpermd vpermpd vpermps vpermq vperm2i128 vextracti128 vinserti128 vpmaskmovd vpmaskmovq vpsllvd vpsllvq vpsravd vpsrlvd vpsrlvq vgatherdpd vgatherqpd vgatherdps vgatherqps vpgatherdd vpgatherqd vpgatherdq vpgatherqq xabort xbegin xend xtest andn bextr blci blcic blsi blsic blcfill blsfill blcmsk blsmsk blsr blcs bzhi mulx pdep pext rorx sarx shlx shrx tzcnt tzmsk t1mskc valignd valignq vblendmpd vblendmps vbroadcastf32x4 vbroadcastf64x4 vbroadcasti32x4 vbroadcasti64x4 vcompresspd vcompressps vcvtpd2udq vcvtps2udq vcvtsd2usi vcvtss2usi vcvttpd2udq vcvttps2udq vcvttsd2usi vcvttss2usi vcvtudq2pd vcvtudq2ps vcvtusi2sd vcvtusi2ss vexpandpd vexpandps vextractf32x4 vextractf64x4 vextracti32x4 vextracti64x4 vfixupimmpd vfixupimmps vfixupimmsd vfixupimmss vgetexppd vgetexpps vgetexpsd vgetexpss vgetmantpd vgetmantps vgetmantsd vgetmantss vinsertf32x4 vinsertf64x4 vinserti32x4 vinserti64x4 vmovdqa32 vmovdqa64 vmovdqu32 vmovdqu64 vpabsq vpandd vpandnd vpandnq vpandq vpblendmd vpblendmq vpcmpltd vpcmpled vpcmpneqd vpcmpnltd vpcmpnled vpcmpd vpcmpltq vpcmpleq vpcmpneqq vpcmpnltq vpcmpnleq vpcmpq vpcmpequd vpcmpltud vpcmpleud vpcmpnequd vpcmpnltud vpcmpnleud vpcmpud vpcmpequq vpcmpltuq vpcmpleuq vpcmpnequq vpcmpnltuq vpcmpnleuq vpcmpuq vpcompressd vpcompressq vpermi2d vpermi2pd vpermi2ps vpermi2q vpermt2d vpermt2pd vpermt2ps vpermt2q vpexpandd vpexpandq vpmaxsq vpmaxuq vpminsq vpminuq vpmovdb vpmovdw vpmovqb vpmovqd vpmovqw vpmovsdb vpmovsdw vpmovsqb vpmovsqd vpmovsqw vpmovusdb vpmovusdw vpmovusqb vpmovusqd vpmovusqw vpord vporq vprold vprolq vprolvd vprolvq vprord vprorq vprorvd vprorvq vpscatterdd vpscatterdq vpscatterqd vpscatterqq vpsraq vpsravq vpternlogd vpternlogq vptestmd vptestmq vptestnmd vptestnmq vpxord vpxorq vrcp14pd vrcp14ps vrcp14sd vrcp14ss vrndscalepd vrndscaleps vrndscalesd vrndscaless vrsqrt14pd vrsqrt14ps vrsqrt14sd vrsqrt14ss vscalefpd vscalefps vscalefsd vscalefss vscatterdpd vscatterdps vscatterqpd vscatterqps vshuff32x4 vshuff64x2 vshufi32x4 vshufi64x2 kandnw kandw kmovw knotw kortestw korw kshiftlw kshiftrw kunpckbw kxnorw kxorw vpbroadcastmb2q vpbroadcastmw2d vpconflictd vpconflictq vplzcntd vplzcntq vexp2pd vexp2ps vrcp28pd vrcp28ps vrcp28sd vrcp28ss vrsqrt28pd vrsqrt28ps vrsqrt28sd vrsqrt28ss vgatherpf0dpd vgatherpf0dps vgatherpf0qpd vgatherpf0qps vgatherpf1dpd vgatherpf1dps vgatherpf1qpd vgatherpf1qps vscatterpf0dpd vscatterpf0dps vscatterpf0qpd vscatterpf0qps vscatterpf1dpd vscatterpf1dps vscatterpf1qpd vscatterpf1qps prefetchwt1 bndmk bndcl bndcu bndcn bndmov bndldx bndstx sha1rnds4 sha1nexte sha1msg1 sha1msg2 sha256rnds2 sha256msg1 sha256msg2 hint_nop0 hint_nop1 hint_nop2 hint_nop3 hint_nop4 hint_nop5 hint_nop6 hint_nop7 hint_nop8 hint_nop9 hint_nop10 hint_nop11 hint_nop12 hint_nop13 hint_nop14 hint_nop15 hint_nop16 hint_nop17 hint_nop18 hint_nop19 hint_nop20 hint_nop21 hint_nop22 hint_nop23 hint_nop24 hint_nop25 hint_nop26 hint_nop27 hint_nop28 hint_nop29 hint_nop30 hint_nop31 hint_nop32 hint_nop33 hint_nop34 hint_nop35 hint_nop36 hint_nop37 hint_nop38 hint_nop39 hint_nop40 hint_nop41 hint_nop42 hint_nop43 hint_nop44 hint_nop45 hint_nop46 hint_nop47 hint_nop48 hint_nop49 hint_nop50 hint_nop51 hint_nop52 hint_nop53 hint_nop54 hint_nop55 hint_nop56 hint_nop57 hint_nop58 hint_nop59 hint_nop60 hint_nop61 hint_nop62 hint_nop63",built_in:"ip eip rip al ah bl bh cl ch dl dh sil dil bpl spl r8b r9b r10b r11b r12b r13b r14b r15b ax bx cx dx si di bp sp r8w r9w r10w r11w r12w r13w r14w r15w eax ebx ecx edx esi edi ebp esp eip r8d r9d r10d r11d r12d r13d r14d r15d rax rbx rcx rdx rsi rdi rbp rsp r8 r9 r10 r11 r12 r13 r14 r15 cs ds es fs gs ss st st0 st1 st2 st3 st4 st5 st6 st7 mm0 mm1 mm2 mm3 mm4 mm5 mm6 mm7 xmm0 xmm1 xmm2 xmm3 xmm4 xmm5 xmm6 xmm7 xmm8 xmm9 xmm10 xmm11 xmm12 xmm13 xmm14 xmm15 xmm16 xmm17 xmm18 xmm19 xmm20 xmm21 xmm22 xmm23 xmm24 xmm25 xmm26 xmm27 xmm28 xmm29 xmm30 xmm31 ymm0 ymm1 ymm2 ymm3 ymm4 ymm5 ymm6 ymm7 ymm8 ymm9 ymm10 ymm11 ymm12 ymm13 ymm14 ymm15 ymm16 ymm17 ymm18 ymm19 ymm20 ymm21 ymm22 ymm23 ymm24 ymm25 ymm26 ymm27 ymm28 ymm29 ymm30 ymm31 zmm0 zmm1 zmm2 zmm3 zmm4 zmm5 zmm6 zmm7 zmm8 zmm9 zmm10 zmm11 zmm12 zmm13 zmm14 zmm15 zmm16 zmm17 zmm18 zmm19 zmm20 zmm21 zmm22 zmm23 zmm24 zmm25 zmm26 zmm27 zmm28 zmm29 zmm30 zmm31 k0 k1 k2 k3 k4 k5 k6 k7 bnd0 bnd1 bnd2 bnd3 cr0 cr1 cr2 cr3 cr4 cr8 dr0 dr1 dr2 dr3 dr8 tr3 tr4 tr5 tr6 tr7 r0 r1 r2 r3 r4 r5 r6 r7 r0b r1b r2b r3b r4b r5b r6b r7b r0w r1w r2w r3w r4w r5w r6w r7w r0d r1d r2d r3d r4d r5d r6d r7d r0h r1h r2h r3h r0l r1l r2l r3l r4l r5l r6l r7l r8l r9l r10l r11l r12l r13l r14l r15l db dw dd dq dt ddq do dy dz resb resw resd resq rest resdq reso resy resz incbin equ times byte word dword qword nosplit rel abs seg wrt strict near far a32 ptr",meta:"%define %xdefine %+ %undef %defstr %deftok %assign %strcat %strlen %substr %rotate %elif %else %endif %if %ifmacro %ifctx %ifidn %ifidni %ifid %ifnum %ifstr %iftoken %ifempty %ifenv %error %warning %fatal %rep %endrep %include %push %pop %repl %pathsearch %depend %use %arg %stacksize %local %line %comment %endcomment .nolist __FILE__ __LINE__ __SECT__ __BITS__ __OUTPUT_FORMAT__ __DATE__ __TIME__ __DATE_NUM__ __TIME_NUM__ __UTC_DATE__ __UTC_TIME__ __UTC_DATE_NUM__ __UTC_TIME_NUM__ __PASS__ struc endstruc istruc at iend align alignb sectalign daz nodaz up down zero default option assume public bits use16 use32 use64 default section segment absolute extern global common cpu float __utf16__ __utf16le__ __utf16be__ __utf32__ __utf32le__ __utf32be__ __float8__ __float16__ __float32__ __float64__ __float80m__ __float80e__ __float128l__ __float128h__ __Infinity__ __QNaN__ __SNaN__ Inf NaN QNaN SNaN float8 float16 float32 float64 float80m float80e float128l float128h __FLOAT_DAZ__ __FLOAT_ROUND__ __FLOAT__"},contains:[s.COMMENT(";","$",{relevance:0}),{className:"number",variants:[{begin:"\\b(?:([0-9][0-9_]*)?\\.[0-9_]*(?:[eE][+-]?[0-9_]+)?|(0[Xx])?[0-9][0-9_]*\\.?[0-9_]*(?:[pP](?:[+-]?[0-9_]+)?)?)\\b",relevance:0},{begin:"\\$[0-9][0-9A-Fa-f]*",relevance:0},{begin:"\\b(?:[0-9A-Fa-f][0-9A-Fa-f_]*[Hh]|[0-9][0-9_]*[DdTt]?|[0-7][0-7_]*[QqOo]|[0-1][0-1_]*[BbYy])\\b"},{begin:"\\b(?:0[Xx][0-9A-Fa-f_]+|0[DdTt][0-9_]+|0[QqOo][0-7_]+|0[BbYy][0-1_]+)\\b"}]},s.QUOTE_STRING_MODE,{className:"string",variants:[{begin:"'",end:"[^\\\\]'"},{begin:"`",end:"[^\\\\]`"}],relevance:0},{className:"symbol",variants:[{begin:"^\\s*[A-Za-z._?][A-Za-z0-9_$#@~.?]*(:|\\s+label)"},{begin:"^\\s*%%[A-Za-z0-9_$#@~.?]*:"}],relevance:0},{className:"subst",begin:"%[0-9]+",relevance:0},{className:"subst",begin:"%!S+",relevance:0},{className:"meta",begin:/^\s*\.[\w_-]+/}]}}}()); \ No newline at end of file diff --git a/book/index.html b/book/index.html new file mode 100644 index 00000000..cda37a5a --- /dev/null +++ b/book/index.html @@ -0,0 +1,222 @@ + + + + + + The x4c Book - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

The x4c Book

+

This book provides an introduction to the P4 language using the x4c compiler. +The presentation is by example. Each concept is introduced through example P4 +code and programs - then demonstrated using simple harnesses that pass packets +through compiled P4 pipelines.

+

A basic knowledge of programming and networking is assumed. The x4c Rust +compilation target will be used in this book, so a working knowledge of +Rust is also good to have.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/intro.html b/book/intro.html new file mode 100644 index 00000000..cda37a5a --- /dev/null +++ b/book/intro.html @@ -0,0 +1,222 @@ + + + + + + The x4c Book - The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

The x4c Book

+

This book provides an introduction to the P4 language using the x4c compiler. +The presentation is by example. Each concept is introduced through example P4 +code and programs - then demonstrated using simple harnesses that pass packets +through compiled P4 pipelines.

+

A basic knowledge of programming and networking is assumed. The x4c Rust +compilation target will be used in this book, so a working knowledge of +Rust is also good to have.

+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/mark.min.js b/book/mark.min.js new file mode 100644 index 00000000..16362318 --- /dev/null +++ b/book/mark.min.js @@ -0,0 +1,7 @@ +/*!*************************************************** +* mark.js v8.11.1 +* https://markjs.io/ +* Copyright (c) 2014–2018, Julian Kühnel +* Released under the MIT license https://git.io/vwTVl +*****************************************************/ +!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.Mark=t()}(this,function(){"use strict";var e="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},t=function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")},n=function(){function e(e,t){for(var n=0;n1&&void 0!==arguments[1])||arguments[1],i=arguments.length>2&&void 0!==arguments[2]?arguments[2]:[],o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:5e3;t(this,e),this.ctx=n,this.iframes=r,this.exclude=i,this.iframesTimeout=o}return n(e,[{key:"getContexts",value:function(){var e=[];return(void 0!==this.ctx&&this.ctx?NodeList.prototype.isPrototypeOf(this.ctx)?Array.prototype.slice.call(this.ctx):Array.isArray(this.ctx)?this.ctx:"string"==typeof this.ctx?Array.prototype.slice.call(document.querySelectorAll(this.ctx)):[this.ctx]:[]).forEach(function(t){var n=e.filter(function(e){return e.contains(t)}).length>0;-1!==e.indexOf(t)||n||e.push(t)}),e}},{key:"getIframeContents",value:function(e,t){var n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(){},r=void 0;try{var i=e.contentWindow;if(r=i.document,!i||!r)throw new Error("iframe inaccessible")}catch(e){n()}r&&t(r)}},{key:"isIframeBlank",value:function(e){var t="about:blank",n=e.getAttribute("src").trim();return e.contentWindow.location.href===t&&n!==t&&n}},{key:"observeIframeLoad",value:function(e,t,n){var r=this,i=!1,o=null,a=function a(){if(!i){i=!0,clearTimeout(o);try{r.isIframeBlank(e)||(e.removeEventListener("load",a),r.getIframeContents(e,t,n))}catch(e){n()}}};e.addEventListener("load",a),o=setTimeout(a,this.iframesTimeout)}},{key:"onIframeReady",value:function(e,t,n){try{"complete"===e.contentWindow.document.readyState?this.isIframeBlank(e)?this.observeIframeLoad(e,t,n):this.getIframeContents(e,t,n):this.observeIframeLoad(e,t,n)}catch(e){n()}}},{key:"waitForIframes",value:function(e,t){var n=this,r=0;this.forEachIframe(e,function(){return!0},function(e){r++,n.waitForIframes(e.querySelector("html"),function(){--r||t()})},function(e){e||t()})}},{key:"forEachIframe",value:function(t,n,r){var i=this,o=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},a=t.querySelectorAll("iframe"),s=a.length,c=0;a=Array.prototype.slice.call(a);var u=function(){--s<=0&&o(c)};s||u(),a.forEach(function(t){e.matches(t,i.exclude)?u():i.onIframeReady(t,function(e){n(t)&&(c++,r(e)),u()},u)})}},{key:"createIterator",value:function(e,t,n){return document.createNodeIterator(e,t,n,!1)}},{key:"createInstanceOnIframe",value:function(t){return new e(t.querySelector("html"),this.iframes)}},{key:"compareNodeIframe",value:function(e,t,n){if(e.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_PRECEDING){if(null===t)return!0;if(t.compareDocumentPosition(n)&Node.DOCUMENT_POSITION_FOLLOWING)return!0}return!1}},{key:"getIteratorNode",value:function(e){var t=e.previousNode();return{prevNode:t,node:null===t?e.nextNode():e.nextNode()&&e.nextNode()}}},{key:"checkIframeFilter",value:function(e,t,n,r){var i=!1,o=!1;return r.forEach(function(e,t){e.val===n&&(i=t,o=e.handled)}),this.compareNodeIframe(e,t,n)?(!1!==i||o?!1===i||o||(r[i].handled=!0):r.push({val:n,handled:!0}),!0):(!1===i&&r.push({val:n,handled:!1}),!1)}},{key:"handleOpenIframes",value:function(e,t,n,r){var i=this;e.forEach(function(e){e.handled||i.getIframeContents(e.val,function(e){i.createInstanceOnIframe(e).forEachNode(t,n,r)})})}},{key:"iterateThroughNodes",value:function(e,t,n,r,i){for(var o,a=this,s=this.createIterator(t,e,r),c=[],u=[],l=void 0,h=void 0;void 0,o=a.getIteratorNode(s),h=o.prevNode,l=o.node;)this.iframes&&this.forEachIframe(t,function(e){return a.checkIframeFilter(l,h,e,c)},function(t){a.createInstanceOnIframe(t).forEachNode(e,function(e){return u.push(e)},r)}),u.push(l);u.forEach(function(e){n(e)}),this.iframes&&this.handleOpenIframes(c,e,n,r),i()}},{key:"forEachNode",value:function(e,t,n){var r=this,i=arguments.length>3&&void 0!==arguments[3]?arguments[3]:function(){},o=this.getContexts(),a=o.length;a||i(),o.forEach(function(o){var s=function(){r.iterateThroughNodes(e,o,t,n,function(){--a<=0&&i()})};r.iframes?r.waitForIframes(o,s):s()})}}],[{key:"matches",value:function(e,t){var n="string"==typeof t?[t]:t,r=e.matches||e.matchesSelector||e.msMatchesSelector||e.mozMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector;if(r){var i=!1;return n.every(function(t){return!r.call(e,t)||(i=!0,!1)}),i}return!1}}]),e}(),o=function(){function e(n){t(this,e),this.opt=r({},{diacritics:!0,synonyms:{},accuracy:"partially",caseSensitive:!1,ignoreJoiners:!1,ignorePunctuation:[],wildcards:"disabled"},n)}return n(e,[{key:"create",value:function(e){return"disabled"!==this.opt.wildcards&&(e=this.setupWildcardsRegExp(e)),e=this.escapeStr(e),Object.keys(this.opt.synonyms).length&&(e=this.createSynonymsRegExp(e)),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),this.opt.diacritics&&(e=this.createDiacriticsRegExp(e)),e=this.createMergedBlanksRegExp(e),(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.createJoinersRegExp(e)),"disabled"!==this.opt.wildcards&&(e=this.createWildcardsRegExp(e)),e=this.createAccuracyRegExp(e),new RegExp(e,"gm"+(this.opt.caseSensitive?"":"i"))}},{key:"escapeStr",value:function(e){return e.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,"\\$&")}},{key:"createSynonymsRegExp",value:function(e){var t=this.opt.synonyms,n=this.opt.caseSensitive?"":"i",r=this.opt.ignoreJoiners||this.opt.ignorePunctuation.length?"\0":"";for(var i in t)if(t.hasOwnProperty(i)){var o=t[i],a="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(i):this.escapeStr(i),s="disabled"!==this.opt.wildcards?this.setupWildcardsRegExp(o):this.escapeStr(o);""!==a&&""!==s&&(e=e.replace(new RegExp("("+this.escapeStr(a)+"|"+this.escapeStr(s)+")","gm"+n),r+"("+this.processSynonyms(a)+"|"+this.processSynonyms(s)+")"+r))}return e}},{key:"processSynonyms",value:function(e){return(this.opt.ignoreJoiners||this.opt.ignorePunctuation.length)&&(e=this.setupIgnoreJoinersRegExp(e)),e}},{key:"setupWildcardsRegExp",value:function(e){return(e=e.replace(/(?:\\)*\?/g,function(e){return"\\"===e.charAt(0)?"?":""})).replace(/(?:\\)*\*/g,function(e){return"\\"===e.charAt(0)?"*":""})}},{key:"createWildcardsRegExp",value:function(e){var t="withSpaces"===this.opt.wildcards;return e.replace(/\u0001/g,t?"[\\S\\s]?":"\\S?").replace(/\u0002/g,t?"[\\S\\s]*?":"\\S*")}},{key:"setupIgnoreJoinersRegExp",value:function(e){return e.replace(/[^(|)\\]/g,function(e,t,n){var r=n.charAt(t+1);return/[(|)\\]/.test(r)||""===r?e:e+"\0"})}},{key:"createJoinersRegExp",value:function(e){var t=[],n=this.opt.ignorePunctuation;return Array.isArray(n)&&n.length&&t.push(this.escapeStr(n.join(""))),this.opt.ignoreJoiners&&t.push("\\u00ad\\u200b\\u200c\\u200d"),t.length?e.split(/\u0000+/).join("["+t.join("")+"]*"):e}},{key:"createDiacriticsRegExp",value:function(e){var t=this.opt.caseSensitive?"":"i",n=this.opt.caseSensitive?["aàáảãạăằắẳẵặâầấẩẫậäåāą","AÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćč","CÇĆČ","dđď","DĐĎ","eèéẻẽẹêềếểễệëěēę","EÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïī","IÌÍỈĨỊÎÏĪ","lł","LŁ","nñňń","NÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøō","OÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rř","RŘ","sšśșş","SŠŚȘŞ","tťțţ","TŤȚŢ","uùúủũụưừứửữựûüůū","UÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿ","YÝỲỶỸỴŸ","zžżź","ZŽŻŹ"]:["aàáảãạăằắẳẵặâầấẩẫậäåāąAÀÁẢÃẠĂẰẮẲẴẶÂẦẤẨẪẬÄÅĀĄ","cçćčCÇĆČ","dđďDĐĎ","eèéẻẽẹêềếểễệëěēęEÈÉẺẼẸÊỀẾỂỄỆËĚĒĘ","iìíỉĩịîïīIÌÍỈĨỊÎÏĪ","lłLŁ","nñňńNÑŇŃ","oòóỏõọôồốổỗộơởỡớờợöøōOÒÓỎÕỌÔỒỐỔỖỘƠỞỠỚỜỢÖØŌ","rřRŘ","sšśșşSŠŚȘŞ","tťțţTŤȚŢ","uùúủũụưừứửữựûüůūUÙÚỦŨỤƯỪỨỬỮỰÛÜŮŪ","yýỳỷỹỵÿYÝỲỶỸỴŸ","zžżźZŽŻŹ"],r=[];return e.split("").forEach(function(i){n.every(function(n){if(-1!==n.indexOf(i)){if(r.indexOf(n)>-1)return!1;e=e.replace(new RegExp("["+n+"]","gm"+t),"["+n+"]"),r.push(n)}return!0})}),e}},{key:"createMergedBlanksRegExp",value:function(e){return e.replace(/[\s]+/gim,"[\\s]+")}},{key:"createAccuracyRegExp",value:function(e){var t=this,n=this.opt.accuracy,r="string"==typeof n?n:n.value,i="";switch(("string"==typeof n?[]:n.limiters).forEach(function(e){i+="|"+t.escapeStr(e)}),r){case"partially":default:return"()("+e+")";case"complementary":return"()([^"+(i="\\s"+(i||this.escapeStr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~¡¿")))+"]*"+e+"[^"+i+"]*)";case"exactly":return"(^|\\s"+i+")("+e+")(?=$|\\s"+i+")"}}}]),e}(),a=function(){function a(e){t(this,a),this.ctx=e,this.ie=!1;var n=window.navigator.userAgent;(n.indexOf("MSIE")>-1||n.indexOf("Trident")>-1)&&(this.ie=!0)}return n(a,[{key:"log",value:function(t){var n=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"debug",r=this.opt.log;this.opt.debug&&"object"===(void 0===r?"undefined":e(r))&&"function"==typeof r[n]&&r[n]("mark.js: "+t)}},{key:"getSeparatedKeywords",value:function(e){var t=this,n=[];return e.forEach(function(e){t.opt.separateWordSearch?e.split(" ").forEach(function(e){e.trim()&&-1===n.indexOf(e)&&n.push(e)}):e.trim()&&-1===n.indexOf(e)&&n.push(e)}),{keywords:n.sort(function(e,t){return t.length-e.length}),length:n.length}}},{key:"isNumeric",value:function(e){return Number(parseFloat(e))==e}},{key:"checkRanges",value:function(e){var t=this;if(!Array.isArray(e)||"[object Object]"!==Object.prototype.toString.call(e[0]))return this.log("markRanges() will only accept an array of objects"),this.opt.noMatch(e),[];var n=[],r=0;return e.sort(function(e,t){return e.start-t.start}).forEach(function(e){var i=t.callNoMatchOnInvalidRanges(e,r),o=i.start,a=i.end;i.valid&&(e.start=o,e.length=a-o,n.push(e),r=a)}),n}},{key:"callNoMatchOnInvalidRanges",value:function(e,t){var n=void 0,r=void 0,i=!1;return e&&void 0!==e.start?(r=(n=parseInt(e.start,10))+parseInt(e.length,10),this.isNumeric(e.start)&&this.isNumeric(e.length)&&r-t>0&&r-n>0?i=!0:(this.log("Ignoring invalid or overlapping range: "+JSON.stringify(e)),this.opt.noMatch(e))):(this.log("Ignoring invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:n,end:r,valid:i}}},{key:"checkWhitespaceRanges",value:function(e,t,n){var r=void 0,i=!0,o=n.length,a=t-o,s=parseInt(e.start,10)-a;return(r=(s=s>o?o:s)+parseInt(e.length,10))>o&&(r=o,this.log("End range automatically set to the max value of "+o)),s<0||r-s<0||s>o||r>o?(i=!1,this.log("Invalid range: "+JSON.stringify(e)),this.opt.noMatch(e)):""===n.substring(s,r).replace(/\s+/g,"")&&(i=!1,this.log("Skipping whitespace only range: "+JSON.stringify(e)),this.opt.noMatch(e)),{start:s,end:r,valid:i}}},{key:"getTextNodes",value:function(e){var t=this,n="",r=[];this.iterator.forEachNode(NodeFilter.SHOW_TEXT,function(e){r.push({start:n.length,end:(n+=e.textContent).length,node:e})},function(e){return t.matchesExclude(e.parentNode)?NodeFilter.FILTER_REJECT:NodeFilter.FILTER_ACCEPT},function(){e({value:n,nodes:r})})}},{key:"matchesExclude",value:function(e){return i.matches(e,this.opt.exclude.concat(["script","style","title","head","html"]))}},{key:"wrapRangeInTextNode",value:function(e,t,n){var r=this.opt.element?this.opt.element:"mark",i=e.splitText(t),o=i.splitText(n-t),a=document.createElement(r);return a.setAttribute("data-markjs","true"),this.opt.className&&a.setAttribute("class",this.opt.className),a.textContent=i.textContent,i.parentNode.replaceChild(a,i),o}},{key:"wrapRangeInMappedTextNode",value:function(e,t,n,r,i){var o=this;e.nodes.every(function(a,s){var c=e.nodes[s+1];if(void 0===c||c.start>t){if(!r(a.node))return!1;var u=t-a.start,l=(n>a.end?a.end:n)-a.start,h=e.value.substr(0,a.start),f=e.value.substr(l+a.start);if(a.node=o.wrapRangeInTextNode(a.node,u,l),e.value=h+f,e.nodes.forEach(function(t,n){n>=s&&(e.nodes[n].start>0&&n!==s&&(e.nodes[n].start-=l),e.nodes[n].end-=l)}),n-=l,i(a.node.previousSibling,a.start),!(n>a.end))return!1;t=a.end}return!0})}},{key:"wrapGroups",value:function(e,t,n,r){return r((e=this.wrapRangeInTextNode(e,t,t+n)).previousSibling),e}},{key:"separateGroups",value:function(e,t,n,r,i){for(var o=t.length,a=1;a-1&&r(t[a],e)&&(e=this.wrapGroups(e,s,t[a].length,i))}return e}},{key:"wrapMatches",value:function(e,t,n,r,i){var o=this,a=0===t?0:t+1;this.getTextNodes(function(t){t.nodes.forEach(function(t){t=t.node;for(var i=void 0;null!==(i=e.exec(t.textContent))&&""!==i[a];){if(o.opt.separateGroups)t=o.separateGroups(t,i,a,n,r);else{if(!n(i[a],t))continue;var s=i.index;if(0!==a)for(var c=1;c + + + + + The x4c Book + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + +
+ +
+ + + + + + + + +
+
+

The x4c Book

+

This book provides an introduction to the P4 language using the x4c compiler. +The presentation is by example. Each concept is introduced through example P4 +code and programs - then demonstrated using simple harnesses that pass packets +through compiled P4 pipelines.

+

A basic knowledge of programming and networking is assumed. The x4c Rust +compilation target will be used in this book, so a working knowledge of +Rust is also good to have.

+

The Basics

+

This chapter will take you from zero to a simple hello-world program in P4. +This will include.

+
    +
  • Getting a Rust toolchain setup and installing the x4c compiler.
  • +
  • Compiling a P4 hello world program into a Rust program.
  • +
  • Writing a bit of Rust code to push packets through the our compiled P4 +pipelines.
  • +
+

Installation

+

Rust

+

The first thing we'll need to do is install Rust. We'll be using a tool called +rustup. On Unix/Linux like platforms, simply run the +following from your terminal. For other platforms see the rustup docs.

+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
+
+

It may be necessary to restart your shell session after installing Rust.

+

x4c

+

Now we will install the x4c compiler using the rust cargo tool.

+
cargo install --git https://github.com/oxidecomputer/p4 x4c
+
+

You should now be able to run x4c.

+
x4c --help
+x4c 0.1
+
+USAGE:
+    x4c [OPTIONS] <FILENAME> [TARGET]
+
+ARGS:
+    <FILENAME>    File to compile
+    <TARGET>      What target to generate code for [default: rust] [possible values: rust,
+                  red-hawk, docs]
+
+OPTIONS:
+        --check          Just check code, do not compile
+    -h, --help           Print help information
+    -o, --out <OUT>      Filename to write generated code to [default: out.rs]
+        --show-ast       Show parsed abstract syntax tree
+        --show-hlir      Show high-level intermediate representation info
+        --show-pre       Show parsed preprocessor info
+        --show-tokens    Show parsed lexical tokens
+    -V, --version        Print version information
+
+

That's it! We're now ready to dive into P4 code.

+

Hello World

+

Let's start out our introduction of P4 with the obligatory hello world program.

+

Parsing

+

The first bit of programmable logic packets hit in a P4 program is a parser. +Parsers do the following.

+
    +
  1. Describe a state machine packet parsing.
  2. +
  3. Extract raw data into headers with typed fields.
  4. +
  5. Decide if a packet should be accepted or rejected based on parsed structure.
  6. +
+

In the code below, we can see that parsers are defined somewhat like functions +in general-purpose programming languages. They take a set of parameters and have +a curly-brace delimited block of code that acts over those parameters.

+

Each of the parameters has an optional direction that we see here as out or +inout, a type, and a name. We'll get to data types in the next section for now +let's focus on what this parser code is doing.

+

The parameters shown here are typical of what you will see for P4 parsers. The +exact set of parameters varies depending on ASIC the P4 code is being compiled +for. But in general, there will always need to be - a packet, set of headers to +extract packet data into and a bit of metadata about the packet that the ASIC +has collected.

+
parser parse (
+    packet_in pkt,
+    out headers_t headers,
+    inout ingress_metadata_t ingress,
+){
+    state start {
+        pkt.extract(headers.ethernet);
+        transition finish;
+    }
+
+    state finish {
+        transition accept;
+    }
+}
+
+

Parsers are made up of a set of states and transitions between those states. +Parsers must always include a start state. Our start state extracts an +Ethernet header from the incoming packet and places it in to the headers_t +parameter passed to the parser. We then transition to the finish state where +we simply transition to the implicit accept state. We could have just +transitioned to accept from start, but wanted to show transitions between +user-defined states in this example.

+

Transitioning to the accept state means that the packet will be passed to a +control block for further processing. Control blocks will be covered a few +sections from now. Parsers can also transition to the implicit reject state. +This means that the packet will be dropped and not go on to any further +processing.

+

Data Types

+

There are two primary data types in P4, struct and header types.

+

Structs

+

Structs in P4 are similar to structs you'll find in general purpose programming +languages such as C, Rust, and Go. They are containers for data with typed data +fields. They can contain basic data types, headers as well as other structs.

+

Let's take a look at the structs in use by our hello world program.

+

The first is a structure containing headers for our program to extract packet +data into. This headers_t structure is simple and only contains one header. +However, there may be an arbitrary number of headers in the struct. We'll +discuss headers in the next section.

+
struct headers_t {
+    ethernet_t ethernet;
+}
+
+

The next structure is a bit of metadata provided to our parser by the ASIC. In +our simple example this just includes the port that the packet came from. So if +our code is running on a four port switch, the port field would take on a +value between 0 and 3 depending on which port the packet came in on.

+
struct ingress_metadata_t {
+    bit<16> port;
+}
+
+

As the name suggests bit<16> is a 16-bit value. In P4 the bit<N> type +commonly represents unsigned integer values. We'll get more into the primitive +data types of P4 later.

+

Headers

+

Headers are the result of parsing packets. They are similar in nature to +structures with the following differences.

+
    +
  1. Headers may not contain headers.
  2. +
  3. Headers have a set of methods isValid(), setValid(), and setValid() +that provide a means for parsers and control blocks to coordinate on the +parsed structure of packets as they move through pipelines.
  4. +
+

Let's take a look at the ethernet_h header in our hello world example.

+
header ethernet_h {
+    bit<48> dst;
+    bit<48> src;
+    bit<16> ether_type;
+}
+
+

This header represents a layer-2 +Ethernet frame. +The leading octet is not present as this will be removed by most ASICs. What +remains is the MAC source and destination fields which are each 6 octets / 48 +bits and the ethertype which is 2 octets.

+

Note also that the payload is not included here. This is important. P4 programs +typically operate on packet headers and not packet payloads. In upcoming +examples we'll go over header stacks that include headers at higher layers like +IP, ICMP and TCP.

+

In the parsing code above, when pkt.extract(headers.ethernet) is called, the +values dst, src and ether_type are populated from packet data and the +method setValid() is implicitly called on the headers.ethernet header.

+

Control Blocks

+

Control blocks are where logic goes that decides what will happen to packets +that are parsed successfully. Similar to a parser block, control blocks look a +lot like functions from general purpose programming languages. The signature +(the number and type of arguments) for this control block is a bit different +than the parser block above.

+

The first argument hdr, is the output of the parser block. Note in the parser +signature there is a out headers_t headers parameter, and in this control +block there is a inout headers_t hdr parameter. The out direction in the +parser means that the parser writes to this parameter. The inout direction +in the control block means that the control both reads and writes to this +parameter.

+

The ingress_metadata_t parameter is the same parameter we saw in the parser +block. The egress_metadata_t is similar to ingress_metadata_t. However, +our code uses this parameter to inform the ASIC about how it should treat packets +on egress. This is in contrast to the ingress_metdata_t parameter that is used +by the ASIC to inform our program about details of the packet's ingress.

+
control ingress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+
+    action drop() { }
+
+    action forward(bit<16> port) {
+        egress.port = port;
+    }
+
+    table tbl {
+        key = {
+            ingress.port: exact;
+        }
+        actions = {
+            drop;
+            forward;
+        }
+        default_action = drop;
+        const entries = {
+            16w0 : forward(16w1);
+            16w1 : forward(16w0);
+        }
+    }
+
+    apply {
+        tbl.apply();
+    }
+
+}
+
+

Control blocks are made up of tables, actions and apply blocks. When packet +headers enter a control block, the apply block decides what tables to run the +parameter data through. Tables are described in terms if keys and actions. A +key is an ordered sequence of fields that can be extracted from any of the +control parameters. In the example above we are using the port field from the +ingress parameter to decide what to do with a packet. We are not even +investigating the packet headers at all! We can indeed use header fields in +keys, and an example of doing so will come later.

+

When a table is applied, and there is an entry in the table that matches the key +data, the action corresponding to that key is executed. In our example we have +pre-populated our table with two entries. The first entry says, if the ingress +port is 0, forward the packet to port 1. The second entry says if the ingress +port is 1, forward the packet to port 0. These odd looking prefixes on our +numbers are width specifiers. So 16w0 reads: the value 0 with a width of 16 +bits.

+

Every action that is specified in a table entry must be defined within the +control. In our example, the forward action is defined above. All this action +does is set the port field on the egress metadata to the provided value.

+

The example table also has a default action of drop. This action fires for all +invocations of the table over key data that has no matching entry. So for our +program, any packet coming from a port that is not 0 or 1 will be dropped.

+

The apply block is home to generic procedural code. In our example it's very +simple and only has an apply invocation for our table. However, arbitrary +logic can go in this block, we could even implement the logic of this control +without a table!

+
apply {
+    if (ingress.port == 16w0) {
+        egress.port = 16w1;
+    }
+    if (ingress.port == 16w1) {
+        egress.port = 16w0;
+    }
+}
+
+

Which then begs the question, why have a special table construct at all. Why not +just program everything using logical primitives? Or let programmers define +their own data structures like general purpose programming languages do?

+

Setting the performance arguments aside for the moment, there is something +mechanically special about tables. They can be updated from outside the P4 +program. In the program above we have what are called constant entries defined +directly in the P4 program. This makes presenting a simple program like this +very straight forward, but it is not the way tables are typically populated. The +focus of P4 is on data plane programming e.g., given a packet from the wire what +do we do with it? I prime example of this is packet routing and forwarding.

+

Both routing and forwarding are typically implemented in terms of lookup tables. +Routing is commonly implemented by longest prefix matching on the destination +address of an IP packet and forwarding is commonly implemented by exact table +lookups on layer-2 MAC addresses. How are those lookup tables populated though. +There are various different answers there. Some common ones include routing +protocols like OSPF, or BGP. Address resolution protocols like ARP and NDP. Or +even more simple answers like an administrator statically adding a route to the +system.

+

All of these activities involve either a stateful protocol of some sort or +direct interaction with a user. Neither of those things is possible in the P4 +programming language. It's just about processing packets on the wire and the +mechanisms for keeping state between packets is extremely limited.

+

What P4 implementations do provide is a way for programs written in +general purpose programming languages that are capable of stateful +protocol implementation and user interaction - to modify the tables of a running +P4 program through a runtime API. We'll come back to runtime APIs soon. For now +the point is that the table abstraction allows P4 programs to remain focused on +simple, mostly-stateless packet processing tasks that can be implemented at high +packet rates and leave the problem of table management to the general purpose +programming languages that interact with P4 programs through shared table +manipulation.

+

Package

+

The final bit to show for our hello world program is a package instantiation. +A package is like a constructor function that takes a parser and a set of +control blocks. Packages are typically tied to the ASIC your P4 code will be +executing on. In the example below, we are passing our parser and single control +block to the SoftNPU package. Packages for more complex ASICs may take many +control blocks as arguments.

+
SoftNPU(
+    parse(),
+    ingress()
+) main;
+
+

Full Program

+

Putting it all together, we have a complete P4 hello world program as follows.

+
struct headers_t {
+    ethernet_h ethernet;
+}
+
+struct ingress_metadata_t {
+    bit<16> port;
+    bool drop;
+}
+
+struct egress_metadata_t {
+    bit<16> port;
+    bool drop;
+    bool broadcast;
+}
+
+header ethernet_h {
+    bit<48> dst;
+    bit<48> src;
+    bit<16> ether_type;
+}
+
+parser parse (
+    packet_in pkt,
+    out headers_t headers,
+    inout ingress_metadata_t ingress,
+){
+    state start {
+        pkt.extract(headers.ethernet);
+        transition finish;
+    }
+
+    state finish {
+        transition accept;
+    }
+}
+
+control ingress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+
+    action drop() { }
+
+    action forward(bit<16> port) {
+        egress.port = port;
+    }
+
+    table tbl {
+        key = {
+            ingress.port: exact;
+        }
+        actions = {
+            drop;
+            forward;
+        }
+        default_action = drop;
+        const entries = {
+            16w0 : forward(16w1);
+            16w1 : forward(16w0);
+        }
+    }
+
+    apply {
+        tbl.apply();
+    }
+
+}
+
+// We do not use an egress controller in this example, but one is required for
+// SoftNPU so just use an empty controller here.
+control egress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+
+}
+
+SoftNPU(
+    parse(),
+    ingress(),
+    egress(),
+) main;
+
+

This program will take any packet that has an Ethernet header showing up on port +0, send it out port 1, and vice versa. All other packets will be dropped.

+

In the next section we'll compile this program and run some packets through it!

+

Compile and Run

+

In the previous section we put together a hello world P4 program. In this +section we run that program over a software ASIC called SoftNpu. One of the +capabilities of the x4c compiler is using P4 code directly from Rust code +and we'll be doing that in this example.

+

Below is a Rust program that imports the P4 code developed in the last section, +loads it onto a SoftNpu ASIC instance, and sends some packets through it. We'll +be looking at this program piece-by-piece in the remainder of this section.

+

All of the programs in this book are available as buildable programs in the +oxidecomputer/p4 repository in the +book/code directory.

+
use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+use tests::{expect_frames};
+
+p4_macro::use_p4!(p4 = "book/code/src/bin/hello-world.p4", pipeline_name = "hello");
+
+fn main() -> Result<(), anyhow::Error> {
+    let pipeline = main_pipeline::new(2);
+    let mut npu = SoftNpu::new(2, pipeline, false);
+    let phy1 = npu.phy(0);
+    let phy2 = npu.phy(1);
+
+    npu.run();
+
+    phy1.send(&[TxFrame::new(phy2.mac, 0, b"hello")])?;
+    expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b"hello")]);
+
+    phy2.send(&[TxFrame::new(phy1.mac, 0, b"world")])?;
+    expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b"world")]);
+
+    Ok(())
+}
+

The program starts with a few Rust imports.

+
use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+use tests::{expect_frames};
+

This first line is the SoftNpu implementation that lives in the test crate of +the oxidecomputer/p4 repository. The second is a helper macro that allows us +to make assertions about frames coming from a SoftNpu "physical" port (referred +to as a phy).

+

The next line is using the x4c compiler to translate P4 code into Rust code +and dumping that Rust code into our program. The macro literally expands into +the Rust code emitted by the compiler for the specified P4 source file.

+
p4_macro::use_p4!(p4 = "book/code/src/bin/hello-world.p4", pipeline_name = "hello");
+

The main artifact this produces is a Rust struct called main_pipeline which is used +in the code that comes next.

+
let pipeline = main_pipeline::new(2);
+let mut npu = SoftNpu::new(2, pipeline, false);
+let phy1 = npu.phy(0);
+let phy2 = npu.phy(1);
+

This code is instantiating a pipeline object that encapsulates the logic of our +P4 program. Then a SoftNpu ASIC is constructed with two ports and our pipeline +program. SoftNpu objects provide a phy method that takes a port index to get a +reference to a port that is attached to the ASIC. These port objects are used to +send and receive packets through the ASIC, which uses our compiled P4 code to +process those packets.

+

Next we run our program on the SoftNpu ASIC.

+
npu.run();
+

However, this does not actually do anything until we pass some packets through +it, so lets do that.

+
phy1.send(&[TxFrame::new(phy2.mac, 0, b"hello")])?;
+

This code transmits an Ethernet frame through the first port of the ASIC with a +payload value of "hello". The phy2.mac parameter of the TxFrame sets the +destination MAC address and the 0 for the second parameter is the ethertype +used in the outgoing Ethernet frame.

+

Based on the logic in our P4 program, we would expect this packet to come out +the second port. Let's test that.

+
expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b"hello")]);
+

This code reads a packet from the second ASIC port phy2 (blocking until there +is a packet available) and asserts the following.

+
    +
  • The Ethernet payload is the byte string "hello".
  • +
  • The source MAC address is that of phy1.
  • +
  • The ethertype is 0.
  • +
+

To complete the hello world program, we do the same thing in the opposite +direction. Sending the byte string "world" as an Ethernet payload into port 2 +and assert that it comes out port 1.

+
phy2.send(&[TxFrame::new(phy1.mac, 0, b"world")])?;
+expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b"world")]);
+

The expect_frames macro will also print payloads and the port they came from.

+

When we run this program we see the following.

+
$ cargo run --bin hello-world
+   Compiling x4c-book v0.1.0 (/home/ry/src/p4/book/code)
+    Finished dev [unoptimized + debuginfo] target(s) in 2.05s
+     Running `target/debug/hello-world`
+[phy2] hello
+[phy1] world
+
+

SoftNpu and Target x4c Use Cases.

+

The example above shows using x4c compiled code is a setting that is only +really useful for testing the logic of compiled pipelines and demonstrating how +P4 and x4c compiled pipelines work. This begs the question of what the target +use cases for x4c actually are. It also raises question, why build x4c in the +first place? Why not use the established reference compiler p4c and its +associated reference behavioral model bmv2?

+

A key difference between x4c and the p4c ecosystem is how compilation +and execution concerns are separated. x4c generates free-standing pipelines +that can be used by other code, p4c generates JSON that is interpreted and run +by bmv2.

+

The example above shows how the generation of free-standing runnable pipelines +can be used to test the logic of P4 programs in a lightweight way. We went from +P4 program source to actual packet processing using nothing but the Rust +compiler and package manager. The program is executable in an operating system +independent way and is a great way to get CI going for P4 programs.

+

The free-standing pipeline approach is not limited to self-contained use cases +with packets that are generated and consumed in-program. x4c generated code +conforms to a well defined +Pipeline +interface that can be used to run pipelines anywhere rustc compiled code can +run. Pipelines are even dynamically loadable through dlopen and the like.

+

The x4c authors have used x4c generated pipelines to create virtual ASICs +inside hypervisors that transit real traffic between virtual machines, as well +as P4 programs running inside zones/containers that implement NAT and tunnel +encap/decap capabilities. The mechanics of I/O are deliberately outside the +scope of x4c generated code. Whether you want to use DLPI, XDP, libpcap, +PF_RING, DPDK, etc., is up to you and the harness code you write around your +pipelines!

+

The win with x4c is flexibility. You can compile a free-standing P4 pipeline +and use that pipeline wherever you see fit. The near-term use for x4c focuses +on development and evaluation environments. If you are building a system around +P4 programmable components, but it's not realistic to buy all the +switches/routers/ASICs at the scale you need for testing/development, x4c is an +option. x4c is also a good option for running packets through your pipelines +in a lightweight way in CI.

+

By Example

+

This chapter presents the use of the P4 language and x4c through a series of +examples. This is a living set that will grow over time.

+

VLAN Switch

+

This example presents a simple VLAN switch program. This program allows a single +VLAN id (vid) to be set per port. Any packet arriving at a port with a vid +set must carry that vid in its Ethernet header or it will be dropped. We'll +refer to this as VLAN filtering. If a packet makes it past ingress filtering, +then the forwarding table of the switch is consulted to see what port to send +the packet out. We limit ourselves to a very simple switch here with a static +forwarding table. A MAC learning switch will be presented in a later example. +This switch also does not do flooding for unknown packets, it simply operates on +the lookup table it has. If an egress port is identified via a forwarding table +lookup, then egress VLAN filtering is applied. If the vid on the packet is +present on the egress port then the packet is forwarded out that port.

+

This example is comprised of two programs. A P4 data-plane program and a Rust +control-plane program.

+

P4 Data-Plane Program

+

Let's start by taking a look at the headers for the P4 program.

+
header ethernet_h {
+    bit<48> dst;
+    bit<48> src;
+    bit<16> ether_type;
+}
+
+header vlan_h {
+    bit<3> pcp;
+    bit<1> dei;
+    bit<12> vid;
+    bit<16> ether_type;
+}
+
+struct headers_t {
+    ethernet_h eth;
+    vlan_h vlan;
+}
+
+

An Ethernet frame is normally just 14 bytes with a 6 byte source and destination +plus a two byte ethertype. However, when VLAN tags are present the ethertype is +set to 0x8100 and a VLAN header follows. This header contains a 12-bit vid +as well as an ethertype for the header that follows.

+

A byte-oriented packet diagram shows how these two Ethernet frame variants line +up.

+
                     1
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8
++---------------------------+
+|    src    |    dst    |et |
++---------------------------+
++-----------------------------------+
+|    src    |    dst    |et |pdv|et |
++------------------------------------
+
+

The structure is always the same for the first 14 bytes. So we can take +advantage of that when parsing any type of Ethernet frame. Then we can use the +ethertype field to determine if we are looking at a regular Ethernet frame or a +VLAN-tagged Ethernet frame.

+
parser parse (
+    packet_in pkt,
+    out headers_t h,
+    inout ingress_metadata_t ingress,
+) {
+    state start {
+        pkt.extract(h.eth);
+        if (h.eth.ether_type == 16w0x8100) { transition vlan; } 
+        transition accept;
+    }
+    state vlan {
+        pkt.extract(h.vlan);
+        transition accept;
+    }
+}
+
+

This parser does exactly what we described above. First parse the first 14 bytes +of the packet as an Ethernet frame. Then conditionally parse the VLAN portion of +the Ethernet frame if the ethertype indicates we should do so. In a sense we can +think of the VLAN portion of the Ethernet frame as being it's own independent +header. We are keying our decisions based on the ethertype, just as we would for +layer 3 protocol headers.

+

Our VLAN switch P4 program is broken up into multiple control blocks. We'll +start with the top level control block and then dive into the control blocks it +calls into to implement the switch.

+
control ingress(
+    inout headers_t hdr,
+    inout ingress_metadata_t ingress,
+    inout egress_metadata_t egress,
+) {
+    vlan() vlan;
+    forward() fwd;
+    
+    apply {
+        bit<12> vid = 12w0;
+        if (hdr.vlan.isValid()) {
+            vid = hdr.vlan.vid;
+        }
+
+        // check vlan on ingress
+        bool vlan_ok = false;
+        vlan.apply(ingress.port, vid, vlan_ok);
+        if (vlan_ok == false) {
+            egress.drop = true;
+            return;
+        }
+
+        // apply switch forwarding logic
+        fwd.apply(hdr, egress);
+
+        // check vlan on egress
+        vlan.apply(egress.port, vid, vlan_ok);
+        if (vlan_ok == false) {
+            egress.drop = true;
+            return;
+        }
+    }
+}
+
+

The first thing that is happening in this program is the instantiation of a few +other control blocks.

+
vlan() vlan;
+forward() fwd;
+
+

We'll be using these control blocks to implement the VLAN filtering and switch +forwarding logic. For now let's take a look at the higher level packet +processing logic of the program in the apply block.

+

The first thing we do is start by assuming there is no vid by setting it to +zero. The if the VLAN header is valid we assign the vid from the packet header +to our local vid variable. The isValid header method returns true if +extract was called on that header. Recall from the parser code above, that +extract is only called on hdr.vlan if the ethertype on the Ethernet frame is +0x1800.

+
bit<12> vid = 12w0;
+if (hdr.vlan.isValid()) {
+    vid = hdr.vlan.vid;
+}
+
+

Next apply VLAN filtering logic. First an indicator variable vlan_ok is +initialized to false. Then we pass that indicator variable along with the port +the packet came in on and the vid we determined above to the VLAN control +block.

+
bool vlan_ok = false;
+vlan.apply(ingress.port, vid, vlan_ok);
+if (vlan_ok == false) {
+    egress.drop = true;
+    return;
+}
+
+

Let's take a look at the VLAN control block. The first thing to note here is the +direction of parameters. The port and vid parameters are in parameters, +meaning that the control block can only read from them. The match parameter is +an out parameter meaning the control block can only write to it. Consider this +in the context of the code above. There we are passing in the vlan_ok to the +control block with the expectation that the control block will modify the value +of the variable. The out direction of this control block parameter is what +makes that possible.

+
control vlan(
+    in bit<16> port,
+    in bit<12> vid,
+    out bool match,
+) {
+    action no_vid_for_port() {
+        match = true;
+    }
+
+    action filter(bit<12> port_vid) { 
+        if (port_vid == vid) { match = true; } 
+    }
+    
+    table port_vlan {
+        key             = { port: exact; }
+        actions         = { no_vid_for_port; filter; }
+        default_action  = no_vid_for_port;
+    }
+
+    apply { port_vlan.apply(); }
+}
+
+

Let's look at this control block starting from the table declaration. The +port_vlan table has the port id as the single key element. There are two +possible actions no_vid_for_port and filter. The no_vid_for_port fires +when there is no match for the port id. That action unconditionally sets +match to true. The logic here is that if there is no VLAN configure for a port +e.g., the port is not in the table, then there is no need to do any VLAN +filtering and just pass the packet along.

+

The filter action takes a single parameter port_vid. This value is populated +by the table value entry corresponding to the port key. There are no static +table entries in this P4 program, they are provided by a control plane program +which we'll get to in a bit. The filter logic tests if the port_vid that has +been configured by the control plane matches the vid on the packet. If the +test passes then match is set to true meaning the packet can continue +processing.

+

Popping back up to the top level control block. If vlan_ok was not set to +true in the vlan control block, then we drop the packet. Otherwise we +continue on to further processing - forwarding.

+

Here we are passing the entire header and egress metadata structures into the +fwd control block which is an instantiation of the forward control block +type.

+
fwd.apply(hdr, egress);
+
+

Lets take a look at the forward control block.

+
control forward(
+    inout headers_t hdr,
+    inout egress_metadata_t egress,
+) {
+    action drop() {}
+    action forward(bit<16> port) { egress.port = port; }
+
+    table fib {
+        key             = { hdr.eth.dst: exact; }
+        actions         = { drop; forward; }
+        default_action  = drop;
+    }
+
+    apply { fib.apply(); }
+}
+
+

This simple control block contains a table that maps Ethernet addresses to +ports. The single element key contains an Ethernet destination and the matching +action forward contains a single 16-bit port value. When the Ethernet +destination matches an entry in the table, the egress metadata destination for +the packet is set to the port id that has been set for that table entry.

+

Note that in this control block both parameters have an inout direction, +meaning the control block can both read from and write to these parameters. +Like the vlan control block above, there are no static entries here. Entries +for the table in this control block are filled in by a control-plane program.

+

Popping back up the stack to our top level control block, the remaining code we +have is the following.

+
vlan.apply(egress.port, vid, vlan_ok);
+if (vlan_ok == false) {
+    egress.drop = true;
+    return;
+}
+
+

This is pretty much the same as what we did at the beginning of the apply block. +Except this time, we are passing in the egress port instead of the ingress port. +We are checking the VLAN tags not only for the ingress port, but also for the +egress port.

+

You can find this program in it's entirety +here.

+

Rust Control-Plane Program

+

The main purpose of the Rust control plane program is to manage table entries in +the P4 program. In addition to table management, the program we'll be showing +here also instantiates and runs the P4 code over a virtual ASIC to demonstrate +the complete system working.

+

We'll start top down again. Here is the beginning of our Rust program.

+
use tests::expect_frames;
+use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+
+p4_macro::use_p4!(
+    p4 = "book/code/src/bin/vlan-switch.p4",
+    pipeline_name = "vlan_switch"
+);
+
+fn main() -> Result<(), anyhow::Error> {
+    let mut pipeline = main_pipeline::new(2);
+
+    let m1 = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33];
+    let m2 = [0x44, 0x44, 0x44, 0x44, 0x44, 0x44];
+
+    init_tables(&mut pipeline, m1, m2);
+    run_test(pipeline, m2)
+}
+

After imports, the first thing we are doing is calling the use_p4! macro. This +translates our P4 program into Rust and expands the use_p4! macro in place to +the generated Rust code. This results in the main_pipeline type that we see +instantiated in the first line of the main program. Then we define a few MAC +addresses that we'll get back to later. The remainder of the main code +performs the two functions described above. The init_tables function acts as a +control plane for our P4 code, setting up the VLAN and forwarding tables. The +run_test code executes our instantiated pipeline over a virtual ASIC, sends +some packets through it, and makes assertions about the results.

+

Control Plane Code

+

Let's jump into the control plane code.

+
fn init_tables(pipeline: &mut main_pipeline, m1: [u8;6], m2: [u8;6]) {
+    // add static forwarding entries
+    pipeline.add_ingress_fwd_fib_entry("forward", &m1, &0u16.to_be_bytes());
+    pipeline.add_ingress_fwd_fib_entry("forward", &m2, &1u16.to_be_bytes());
+
+    // port 0 vlan 47
+    pipeline.add_ingress_vlan_port_vlan_entry(
+        "filter",
+        0u16.to_be_bytes().as_ref(),
+        47u16.to_be_bytes().as_ref(),
+    );
+
+    // sanity check the table
+    let x = pipeline.get_ingress_vlan_port_vlan_entries();
+    println!("{:#?}", x);
+
+    // port 1 vlan 47
+    pipeline.add_ingress_vlan_port_vlan_entry(
+        "filter",
+        1u16.to_be_bytes().as_ref(),
+        47u16.to_be_bytes().as_ref(),
+    );
+
+}
+

The first thing that happens here is the forwarding tables are set up. We add +two entries one for each MAC address. The first MAC address maps to the first +port and the second MAC address maps to the second port.

+

We are using table modification methods from the Rust code that was generated +from our P4 code. A valid question is, how do I know what these are? There are +two ways.

+

Determine Based on P4 Code Structure

+

The naming is deterministic based on the structure of the p4 program. Table +modification functions follow the pattern +<operation>_<control_path>_<table_name>_entry. Where operation one of the +following.

+
    +
  • add
  • +
  • remove
  • +
  • get.
  • +
+

The control_path is based on the names of control instances starting from the +top level ingress controller. In our P4 program, the forwarding table is named +fwd so that is what we see in the function above. If there is a longer chain +of controller instances, the instance names are underscore separated. Finally +the table_name is the name of the table in the control block. This is how we +arrive at the method name above.

+
pipeline.add_fwd_fib_entry(...)
+

Use cargo doc

+

Alternatively you can just run cargo doc to have Cargo generate documentation +for your crate that contains the P4-generated Rust code. This will emit Rust +documentation that includes documentation for the generated code.

+

Now back to the control plane code above. You'll also notice that we are adding +key values and parameter values to the P4 tables as byte slices. At the time of +writing, x4c is not generating high-level table manipulation APIs so we have +to pass everything in as binary serialized data.

+

The semantics of these data buffers are the following.

+
    +
  1. Both key data and match action data (parameters) are passed in in-order.
  2. +
  3. Numeric types are serialized in big-endian byte order.
  4. +
  5. If a set of keys or a set of parameters results in a size that does not land +on a byte-boundary, i.e. 12 bytes like we have in this example, the length of +the buffer is rounded up to the nearest byte boundary.
  6. +
+

After adding the forwarding entries, VLAN table entries are added in the same +manner. A VLAN with the vid of 47 is added to the first and second ports. +Note that we also use a table access method to get all the entries of a table +and print them out to convince ourselves our code is doing what we intend.

+

Test Code

+

Now let's take a look at the test portion of our code.

+
fn run_test(
+    pipeline: main_pipeline,
+    m2: [u8; 6],
+    m3: [u8; 6],
+) -> Result<(), anyhow::Error> {
+    // create and run the softnpu instance
+    let mut npu = SoftNpu::new(2, pipeline, false);
+    let phy1 = npu.phy(0);
+    let phy2 = npu.phy(1);
+    npu.run();
+
+    // send a packet we expect to make it through
+    phy1.send(&[TxFrame::newv(m2, 0, b"blueberry", 47)])?;
+    expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b"blueberry", 47)]);
+
+    // send 3 packets, we expect the first 2 to get filtered by vlan rules
+    phy1.send(&[TxFrame::newv(m2, 0, b"poppyseed", 74)])?; // 74 != 47
+    phy1.send(&[TxFrame::new(m2, 0, b"banana")])?; // no tag
+    phy1.send(&[TxFrame::newv(m2, 0, b"muffin", 47)])?;
+    phy1.send(&[TxFrame::newv(m3, 0, b"nut", 47)])?; // no forwarding entry
+    expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b"muffin", 47)]);
+
+    Ok(())
+}
+

The first thing we do here is create a SoftNpu virtual ASIC instance with 2 +ports that will execute the pipeline we configured with entries in the previous +section. We get references to each ASIC port and run the ASIC.

+

Next we send a few packets through the ASIC to validate that our P4 program is +doing what we expect given how we have configured the tables.

+

The first test passes through a packet we expect to make it through the VLAN +filtering. The next test sends 4 packets in the ASIC, but we expect our P4 +program to filter 3 of them out.

+
    +
  • The first packet has the wrong vid.
  • +
  • The second packet has no vid.
  • +
  • The third packet should make it through.
  • +
  • The fourth packet has no forwarding entry.
  • +
+

Running the test

+

When we run this program we see the following

+
$ cargo run --bin vlan-switch
+    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
+     Running `target/debug/vlan-switch`
+[
+    TableEntry {
+        action_id: "filter",
+        keyset_data: [
+            0,
+            0,
+        ],
+        parameter_data: [
+            0,
+            47,
+        ],
+    },
+]
+[phy2] blueberry
+drop
+drop
+drop
+[phy2] muffin
+
+

The first thing we see is our little sanity check dumping out the VLAN table +after adding a single entry. This has what we expect, mapping the port 0 to +the vid 47.

+

Next we start sending packets through the ASIC. There are two frame constructors +in play here. TxFrame::newv creates an Ethernet frame with a VLAN header and +TxFrame::new creates just a plane old Ethernet frame. The first argument to +each frame constructor is the destination MAC address. The second argument is +the ethertype to use and the third argument is the Ethernet payload.

+

Next we see that our blueberry packet made it through as expected. Then we see +three packets getting dropped as we expect. And finally we see the muffin packet +coming through as expected.

+

You can find this program in it's entirety +here.

+

Guidelines

+

Ths chapter provides guidelines on various aspects of the x4c compiler.

+

Endianness

+

The basic rules for endianness follow. Generally speaking numeric fields are in +big endian when they come in off the wire, little endian while in the program, +and transformed back to big endian on the way back out onto the wire. We refer +to this as confused endian.

+
    +
  1. All numeric packet field data is big endian when enters and leaves a p4 +program.
  2. +
  3. All numeric data, including packet fields is little endian inside a p4 +program.
  4. +
  5. Table keys with the exact and range type defined over bit types are in +little endian.
  6. +
  7. Table keys with the lpm type are in the byte order they appear on the wire.
  8. +
+ +
+ + +
+
+ + + +
+ + + + + + + + + + + + + + + + + + + +
+ + diff --git a/book/searcher.js b/book/searcher.js new file mode 100644 index 00000000..dc03e0a0 --- /dev/null +++ b/book/searcher.js @@ -0,0 +1,483 @@ +"use strict"; +window.search = window.search || {}; +(function search(search) { + // Search functionality + // + // You can use !hasFocus() to prevent keyhandling in your key + // event handlers while the user is typing their search. + + if (!Mark || !elasticlunr) { + return; + } + + //IE 11 Compatibility from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith + if (!String.prototype.startsWith) { + String.prototype.startsWith = function(search, pos) { + return this.substr(!pos || pos < 0 ? 0 : +pos, search.length) === search; + }; + } + + var search_wrap = document.getElementById('search-wrapper'), + searchbar = document.getElementById('searchbar'), + searchbar_outer = document.getElementById('searchbar-outer'), + searchresults = document.getElementById('searchresults'), + searchresults_outer = document.getElementById('searchresults-outer'), + searchresults_header = document.getElementById('searchresults-header'), + searchicon = document.getElementById('search-toggle'), + content = document.getElementById('content'), + + searchindex = null, + doc_urls = [], + results_options = { + teaser_word_count: 30, + limit_results: 30, + }, + search_options = { + bool: "AND", + expand: true, + fields: { + title: {boost: 1}, + body: {boost: 1}, + breadcrumbs: {boost: 0} + } + }, + mark_exclude = [], + marker = new Mark(content), + current_searchterm = "", + URL_SEARCH_PARAM = 'search', + URL_MARK_PARAM = 'highlight', + teaser_count = 0, + + SEARCH_HOTKEY_KEYCODE = 83, + ESCAPE_KEYCODE = 27, + DOWN_KEYCODE = 40, + UP_KEYCODE = 38, + SELECT_KEYCODE = 13; + + function hasFocus() { + return searchbar === document.activeElement; + } + + function removeChildren(elem) { + while (elem.firstChild) { + elem.removeChild(elem.firstChild); + } + } + + // Helper to parse a url into its building blocks. + function parseURL(url) { + var a = document.createElement('a'); + a.href = url; + return { + source: url, + protocol: a.protocol.replace(':',''), + host: a.hostname, + port: a.port, + params: (function(){ + var ret = {}; + var seg = a.search.replace(/^\?/,'').split('&'); + var len = seg.length, i = 0, s; + for (;i': '>', + '"': '"', + "'": ''' + }; + var repl = function(c) { return MAP[c]; }; + return function(s) { + return s.replace(/[&<>'"]/g, repl); + }; + })(); + + function formatSearchMetric(count, searchterm) { + if (count == 1) { + return count + " search result for '" + searchterm + "':"; + } else if (count == 0) { + return "No search results for '" + searchterm + "'."; + } else { + return count + " search results for '" + searchterm + "':"; + } + } + + function formatSearchResult(result, searchterms) { + var teaser = makeTeaser(escapeHTML(result.doc.body), searchterms); + teaser_count++; + + // The ?URL_MARK_PARAM= parameter belongs inbetween the page and the #heading-anchor + var url = doc_urls[result.ref].split("#"); + if (url.length == 1) { // no anchor found + url.push(""); + } + + // encodeURIComponent escapes all chars that could allow an XSS except + // for '. Due to that we also manually replace ' with its url-encoded + // representation (%27). + var searchterms = encodeURIComponent(searchterms.join(" ")).replace(/\'/g, "%27"); + + return '' + result.doc.breadcrumbs + '' + + '' + + teaser + ''; + } + + function makeTeaser(body, searchterms) { + // The strategy is as follows: + // First, assign a value to each word in the document: + // Words that correspond to search terms (stemmer aware): 40 + // Normal words: 2 + // First word in a sentence: 8 + // Then use a sliding window with a constant number of words and count the + // sum of the values of the words within the window. Then use the window that got the + // maximum sum. If there are multiple maximas, then get the last one. + // Enclose the terms in . + var stemmed_searchterms = searchterms.map(function(w) { + return elasticlunr.stemmer(w.toLowerCase()); + }); + var searchterm_weight = 40; + var weighted = []; // contains elements of ["word", weight, index_in_document] + // split in sentences, then words + var sentences = body.toLowerCase().split('. '); + var index = 0; + var value = 0; + var searchterm_found = false; + for (var sentenceindex in sentences) { + var words = sentences[sentenceindex].split(' '); + value = 8; + for (var wordindex in words) { + var word = words[wordindex]; + if (word.length > 0) { + for (var searchtermindex in stemmed_searchterms) { + if (elasticlunr.stemmer(word).startsWith(stemmed_searchterms[searchtermindex])) { + value = searchterm_weight; + searchterm_found = true; + } + }; + weighted.push([word, value, index]); + value = 2; + } + index += word.length; + index += 1; // ' ' or '.' if last word in sentence + }; + index += 1; // because we split at a two-char boundary '. ' + }; + + if (weighted.length == 0) { + return body; + } + + var window_weight = []; + var window_size = Math.min(weighted.length, results_options.teaser_word_count); + + var cur_sum = 0; + for (var wordindex = 0; wordindex < window_size; wordindex++) { + cur_sum += weighted[wordindex][1]; + }; + window_weight.push(cur_sum); + for (var wordindex = 0; wordindex < weighted.length - window_size; wordindex++) { + cur_sum -= weighted[wordindex][1]; + cur_sum += weighted[wordindex + window_size][1]; + window_weight.push(cur_sum); + }; + + if (searchterm_found) { + var max_sum = 0; + var max_sum_window_index = 0; + // backwards + for (var i = window_weight.length - 1; i >= 0; i--) { + if (window_weight[i] > max_sum) { + max_sum = window_weight[i]; + max_sum_window_index = i; + } + }; + } else { + max_sum_window_index = 0; + } + + // add around searchterms + var teaser_split = []; + var index = weighted[max_sum_window_index][2]; + for (var i = max_sum_window_index; i < max_sum_window_index+window_size; i++) { + var word = weighted[i]; + if (index < word[2]) { + // missing text from index to start of `word` + teaser_split.push(body.substring(index, word[2])); + index = word[2]; + } + if (word[1] == searchterm_weight) { + teaser_split.push("") + } + index = word[2] + word[0].length; + teaser_split.push(body.substring(word[2], index)); + if (word[1] == searchterm_weight) { + teaser_split.push("") + } + }; + + return teaser_split.join(''); + } + + function init(config) { + results_options = config.results_options; + search_options = config.search_options; + searchbar_outer = config.searchbar_outer; + doc_urls = config.doc_urls; + searchindex = elasticlunr.Index.load(config.index); + + // Set up events + searchicon.addEventListener('click', function(e) { searchIconClickHandler(); }, false); + searchbar.addEventListener('keyup', function(e) { searchbarKeyUpHandler(); }, false); + document.addEventListener('keydown', function(e) { globalKeyHandler(e); }, false); + // If the user uses the browser buttons, do the same as if a reload happened + window.onpopstate = function(e) { doSearchOrMarkFromUrl(); }; + // Suppress "submit" events so the page doesn't reload when the user presses Enter + document.addEventListener('submit', function(e) { e.preventDefault(); }, false); + + // If reloaded, do the search or mark again, depending on the current url parameters + doSearchOrMarkFromUrl(); + } + + function unfocusSearchbar() { + // hacky, but just focusing a div only works once + var tmp = document.createElement('input'); + tmp.setAttribute('style', 'position: absolute; opacity: 0;'); + searchicon.appendChild(tmp); + tmp.focus(); + tmp.remove(); + } + + // On reload or browser history backwards/forwards events, parse the url and do search or mark + function doSearchOrMarkFromUrl() { + // Check current URL for search request + var url = parseURL(window.location.href); + if (url.params.hasOwnProperty(URL_SEARCH_PARAM) + && url.params[URL_SEARCH_PARAM] != "") { + showSearch(true); + searchbar.value = decodeURIComponent( + (url.params[URL_SEARCH_PARAM]+'').replace(/\+/g, '%20')); + searchbarKeyUpHandler(); // -> doSearch() + } else { + showSearch(false); + } + + if (url.params.hasOwnProperty(URL_MARK_PARAM)) { + var words = decodeURIComponent(url.params[URL_MARK_PARAM]).split(' '); + marker.mark(words, { + exclude: mark_exclude + }); + + var markers = document.querySelectorAll("mark"); + function hide() { + for (var i = 0; i < markers.length; i++) { + markers[i].classList.add("fade-out"); + window.setTimeout(function(e) { marker.unmark(); }, 300); + } + } + for (var i = 0; i < markers.length; i++) { + markers[i].addEventListener('click', hide); + } + } + } + + // Eventhandler for keyevents on `document` + function globalKeyHandler(e) { + if (e.altKey || e.ctrlKey || e.metaKey || e.shiftKey || e.target.type === 'textarea' || e.target.type === 'text' || !hasFocus() && /^(?:input|select|textarea)$/i.test(e.target.nodeName)) { return; } + + if (e.keyCode === ESCAPE_KEYCODE) { + e.preventDefault(); + searchbar.classList.remove("active"); + setSearchUrlParameters("", + (searchbar.value.trim() !== "") ? "push" : "replace"); + if (hasFocus()) { + unfocusSearchbar(); + } + showSearch(false); + marker.unmark(); + } else if (!hasFocus() && e.keyCode === SEARCH_HOTKEY_KEYCODE) { + e.preventDefault(); + showSearch(true); + window.scrollTo(0, 0); + searchbar.select(); + } else if (hasFocus() && e.keyCode === DOWN_KEYCODE) { + e.preventDefault(); + unfocusSearchbar(); + searchresults.firstElementChild.classList.add("focus"); + } else if (!hasFocus() && (e.keyCode === DOWN_KEYCODE + || e.keyCode === UP_KEYCODE + || e.keyCode === SELECT_KEYCODE)) { + // not `:focus` because browser does annoying scrolling + var focused = searchresults.querySelector("li.focus"); + if (!focused) return; + e.preventDefault(); + if (e.keyCode === DOWN_KEYCODE) { + var next = focused.nextElementSibling; + if (next) { + focused.classList.remove("focus"); + next.classList.add("focus"); + } + } else if (e.keyCode === UP_KEYCODE) { + focused.classList.remove("focus"); + var prev = focused.previousElementSibling; + if (prev) { + prev.classList.add("focus"); + } else { + searchbar.select(); + } + } else { // SELECT_KEYCODE + window.location.assign(focused.querySelector('a')); + } + } + } + + function showSearch(yes) { + if (yes) { + search_wrap.classList.remove('hidden'); + searchicon.setAttribute('aria-expanded', 'true'); + } else { + search_wrap.classList.add('hidden'); + searchicon.setAttribute('aria-expanded', 'false'); + var results = searchresults.children; + for (var i = 0; i < results.length; i++) { + results[i].classList.remove("focus"); + } + } + } + + function showResults(yes) { + if (yes) { + searchresults_outer.classList.remove('hidden'); + } else { + searchresults_outer.classList.add('hidden'); + } + } + + // Eventhandler for search icon + function searchIconClickHandler() { + if (search_wrap.classList.contains('hidden')) { + showSearch(true); + window.scrollTo(0, 0); + searchbar.select(); + } else { + showSearch(false); + } + } + + // Eventhandler for keyevents while the searchbar is focused + function searchbarKeyUpHandler() { + var searchterm = searchbar.value.trim(); + if (searchterm != "") { + searchbar.classList.add("active"); + doSearch(searchterm); + } else { + searchbar.classList.remove("active"); + showResults(false); + removeChildren(searchresults); + } + + setSearchUrlParameters(searchterm, "push_if_new_search_else_replace"); + + // Remove marks + marker.unmark(); + } + + // Update current url with ?URL_SEARCH_PARAM= parameter, remove ?URL_MARK_PARAM and #heading-anchor . + // `action` can be one of "push", "replace", "push_if_new_search_else_replace" + // and replaces or pushes a new browser history item. + // "push_if_new_search_else_replace" pushes if there is no `?URL_SEARCH_PARAM=abc` yet. + function setSearchUrlParameters(searchterm, action) { + var url = parseURL(window.location.href); + var first_search = ! url.params.hasOwnProperty(URL_SEARCH_PARAM); + if (searchterm != "" || action == "push_if_new_search_else_replace") { + url.params[URL_SEARCH_PARAM] = searchterm; + delete url.params[URL_MARK_PARAM]; + url.hash = ""; + } else { + delete url.params[URL_MARK_PARAM]; + delete url.params[URL_SEARCH_PARAM]; + } + // A new search will also add a new history item, so the user can go back + // to the page prior to searching. A updated search term will only replace + // the url. + if (action == "push" || (action == "push_if_new_search_else_replace" && first_search) ) { + history.pushState({}, document.title, renderURL(url)); + } else if (action == "replace" || (action == "push_if_new_search_else_replace" && !first_search) ) { + history.replaceState({}, document.title, renderURL(url)); + } + } + + function doSearch(searchterm) { + + // Don't search the same twice + if (current_searchterm == searchterm) { return; } + else { current_searchterm = searchterm; } + + if (searchindex == null) { return; } + + // Do the actual search + var results = searchindex.search(searchterm, search_options); + var resultcount = Math.min(results.length, results_options.limit_results); + + // Display search metrics + searchresults_header.innerText = formatSearchMetric(resultcount, searchterm); + + // Clear and insert results + var searchterms = searchterm.split(' '); + removeChildren(searchresults); + for(var i = 0; i < resultcount ; i++){ + var resultElem = document.createElement('li'); + resultElem.innerHTML = formatSearchResult(results[i], searchterms); + searchresults.appendChild(resultElem); + } + + // Display results + showResults(true); + } + + fetch(path_to_root + 'searchindex.json') + .then(response => response.json()) + .then(json => init(json)) + .catch(error => { // Try to load searchindex.js if fetch failed + var script = document.createElement('script'); + script.src = path_to_root + 'searchindex.js'; + script.onload = () => init(window.search); + document.head.appendChild(script); + }); + + // Exported functions + search.hasFocus = hasFocus; +})(window.search); diff --git a/book/searchindex.js b/book/searchindex.js new file mode 100644 index 00000000..8aa02a9f --- /dev/null +++ b/book/searchindex.js @@ -0,0 +1 @@ +Object.assign(window.search, {"doc_urls":["intro.html#the-x4c-book","01-basics.html#the-basics","01-01-installation.html#installation","01-01-installation.html#rust","01-01-installation.html#x4c","01-02-hello_world.html#hello-world","01-02-hello_world.html#parsing","01-02-hello_world.html#data-types","01-02-hello_world.html#structs","01-02-hello_world.html#headers","01-02-hello_world.html#control-blocks","01-02-hello_world.html#package","01-02-hello_world.html#full-program","01-03-compile_and_run.html#compile-and-run","01-03-compile_and_run.html#softnpu-and-target-x4c-use-cases","02-by-example.html#by-example","02-01-vlan-switch.html#vlan-switch","02-01-vlan-switch.html#p4-data-plane-program","02-01-vlan-switch.html#rust-control-plane-program","02-01-vlan-switch.html#control-plane-code","02-01-vlan-switch.html#test-code","03-guidelines.html#guidelines","03-01-endianness.html#endianness"],"index":{"documentStore":{"docInfo":{"0":{"body":43,"breadcrumbs":4,"title":2},"1":{"body":33,"breadcrumbs":2,"title":1},"10":{"body":519,"breadcrumbs":5,"title":2},"11":{"body":45,"breadcrumbs":4,"title":1},"12":{"body":141,"breadcrumbs":5,"title":2},"13":{"body":374,"breadcrumbs":5,"title":2},"14":{"body":238,"breadcrumbs":8,"title":5},"15":{"body":14,"breadcrumbs":2,"title":1},"16":{"body":98,"breadcrumbs":5,"title":2},"17":{"body":722,"breadcrumbs":7,"title":4},"18":{"body":145,"breadcrumbs":7,"title":4},"19":{"body":271,"breadcrumbs":6,"title":3},"2":{"body":0,"breadcrumbs":3,"title":1},"20":{"body":274,"breadcrumbs":5,"title":2},"21":{"body":8,"breadcrumbs":2,"title":1},"22":{"body":66,"breadcrumbs":3,"title":1},"3":{"body":34,"breadcrumbs":3,"title":1},"4":{"body":99,"breadcrumbs":3,"title":1},"5":{"body":9,"breadcrumbs":5,"title":2},"6":{"body":195,"breadcrumbs":4,"title":1},"7":{"body":8,"breadcrumbs":5,"title":2},"8":{"body":115,"breadcrumbs":4,"title":1},"9":{"body":115,"breadcrumbs":4,"title":1}},"docs":{"0":{"body":"This book provides an introduction to the P4 language using the x4c compiler. The presentation is by example. Each concept is introduced through example P4 code and programs - then demonstrated using simple harnesses that pass packets through compiled P4 pipelines. A basic knowledge of programming and networking is assumed. The x4c Rust compilation target will be used in this book, so a working knowledge of Rust is also good to have.","breadcrumbs":"The x4c Book » The x4c Book","id":"0","title":"The x4c Book"},"1":{"body":"This chapter will take you from zero to a simple hello-world program in P4. This will include. Getting a Rust toolchain setup and installing the x4c compiler. Compiling a P4 hello world program into a Rust program. Writing a bit of Rust code to push packets through the our compiled P4 pipelines.","breadcrumbs":"The Basics » The Basics","id":"1","title":"The Basics"},"10":{"body":"Control blocks are where logic goes that decides what will happen to packets that are parsed successfully. Similar to a parser block, control blocks look a lot like functions from general purpose programming languages. The signature (the number and type of arguments) for this control block is a bit different than the parser block above. The first argument hdr, is the output of the parser block. Note in the parser signature there is a out headers_t headers parameter, and in this control block there is a inout headers_t hdr parameter. The out direction in the parser means that the parser writes to this parameter. The inout direction in the control block means that the control both reads and writes to this parameter. The ingress_metadata_t parameter is the same parameter we saw in the parser block. The egress_metadata_t is similar to ingress_metadata_t. However, our code uses this parameter to inform the ASIC about how it should treat packets on egress. This is in contrast to the ingress_metdata_t parameter that is used by the ASIC to inform our program about details of the packet's ingress. control ingress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { action drop() { } action forward(bit<16> port) { egress.port = port; } table tbl { key = { ingress.port: exact; } actions = { drop; forward; } default_action = drop; const entries = { 16w0 : forward(16w1); 16w1 : forward(16w0); } } apply { tbl.apply(); } } Control blocks are made up of tables, actions and apply blocks. When packet headers enter a control block, the apply block decides what tables to run the parameter data through. Tables are described in terms if keys and actions. A key is an ordered sequence of fields that can be extracted from any of the control parameters. In the example above we are using the port field from the ingress parameter to decide what to do with a packet. We are not even investigating the packet headers at all! We can indeed use header fields in keys, and an example of doing so will come later. When a table is applied, and there is an entry in the table that matches the key data, the action corresponding to that key is executed. In our example we have pre-populated our table with two entries. The first entry says, if the ingress port is 0, forward the packet to port 1. The second entry says if the ingress port is 1, forward the packet to port 0. These odd looking prefixes on our numbers are width specifiers. So 16w0 reads: the value 0 with a width of 16 bits. Every action that is specified in a table entry must be defined within the control. In our example, the forward action is defined above. All this action does is set the port field on the egress metadata to the provided value. The example table also has a default action of drop. This action fires for all invocations of the table over key data that has no matching entry. So for our program, any packet coming from a port that is not 0 or 1 will be dropped. The apply block is home to generic procedural code. In our example it's very simple and only has an apply invocation for our table. However, arbitrary logic can go in this block, we could even implement the logic of this control without a table! apply { if (ingress.port == 16w0) { egress.port = 16w1; } if (ingress.port == 16w1) { egress.port = 16w0; }\n} Which then begs the question, why have a special table construct at all. Why not just program everything using logical primitives? Or let programmers define their own data structures like general purpose programming languages do? Setting the performance arguments aside for the moment, there is something mechanically special about tables. They can be updated from outside the P4 program. In the program above we have what are called constant entries defined directly in the P4 program. This makes presenting a simple program like this very straight forward, but it is not the way tables are typically populated. The focus of P4 is on data plane programming e.g., given a packet from the wire what do we do with it? I prime example of this is packet routing and forwarding. Both routing and forwarding are typically implemented in terms of lookup tables. Routing is commonly implemented by longest prefix matching on the destination address of an IP packet and forwarding is commonly implemented by exact table lookups on layer-2 MAC addresses. How are those lookup tables populated though. There are various different answers there. Some common ones include routing protocols like OSPF, or BGP. Address resolution protocols like ARP and NDP. Or even more simple answers like an administrator statically adding a route to the system. All of these activities involve either a stateful protocol of some sort or direct interaction with a user. Neither of those things is possible in the P4 programming language. It's just about processing packets on the wire and the mechanisms for keeping state between packets is extremely limited. What P4 implementations do provide is a way for programs written in general purpose programming languages that are capable of stateful protocol implementation and user interaction - to modify the tables of a running P4 program through a runtime API. We'll come back to runtime APIs soon. For now the point is that the table abstraction allows P4 programs to remain focused on simple, mostly-stateless packet processing tasks that can be implemented at high packet rates and leave the problem of table management to the general purpose programming languages that interact with P4 programs through shared table manipulation.","breadcrumbs":"The Basics » Hello World » Control Blocks","id":"10","title":"Control Blocks"},"11":{"body":"The final bit to show for our hello world program is a package instantiation. A package is like a constructor function that takes a parser and a set of control blocks. Packages are typically tied to the ASIC your P4 code will be executing on. In the example below, we are passing our parser and single control block to the SoftNPU package. Packages for more complex ASICs may take many control blocks as arguments. SoftNPU( parse(), ingress()\n) main;","breadcrumbs":"The Basics » Hello World » Package","id":"11","title":"Package"},"12":{"body":"Putting it all together, we have a complete P4 hello world program as follows. struct headers_t { ethernet_h ethernet;\n} struct ingress_metadata_t { bit<16> port; bool drop;\n} struct egress_metadata_t { bit<16> port; bool drop; bool broadcast;\n} header ethernet_h { bit<48> dst; bit<48> src; bit<16> ether_type;\n} parser parse ( packet_in pkt, out headers_t headers, inout ingress_metadata_t ingress,\n){ state start { pkt.extract(headers.ethernet); transition finish; } state finish { transition accept; }\n} control ingress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { action drop() { } action forward(bit<16> port) { egress.port = port; } table tbl { key = { ingress.port: exact; } actions = { drop; forward; } default_action = drop; const entries = { 16w0 : forward(16w1); 16w1 : forward(16w0); } } apply { tbl.apply(); } } // We do not use an egress controller in this example, but one is required for\n// SoftNPU so just use an empty controller here.\ncontrol egress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { } SoftNPU( parse(), ingress(), egress(),\n) main; This program will take any packet that has an Ethernet header showing up on port 0, send it out port 1, and vice versa. All other packets will be dropped. In the next section we'll compile this program and run some packets through it!","breadcrumbs":"The Basics » Hello World » Full Program","id":"12","title":"Full Program"},"13":{"body":"In the previous section we put together a hello world P4 program. In this section we run that program over a software ASIC called SoftNpu. One of the capabilities of the x4c compiler is using P4 code directly from Rust code and we'll be doing that in this example. Below is a Rust program that imports the P4 code developed in the last section, loads it onto a SoftNpu ASIC instance, and sends some packets through it. We'll be looking at this program piece-by-piece in the remainder of this section. All of the programs in this book are available as buildable programs in the oxidecomputer/p4 repository in the book/code directory. use tests::softnpu::{RxFrame, SoftNpu, TxFrame};\nuse tests::{expect_frames}; p4_macro::use_p4!(p4 = \"book/code/src/bin/hello-world.p4\", pipeline_name = \"hello\"); fn main() -> Result<(), anyhow::Error> { let pipeline = main_pipeline::new(2); let mut npu = SoftNpu::new(2, pipeline, false); let phy1 = npu.phy(0); let phy2 = npu.phy(1); npu.run(); phy1.send(&[TxFrame::new(phy2.mac, 0, b\"hello\")])?; expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b\"hello\")]); phy2.send(&[TxFrame::new(phy1.mac, 0, b\"world\")])?; expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b\"world\")]); Ok(())\n} The program starts with a few Rust imports. use tests::softnpu::{RxFrame, SoftNpu, TxFrame};\nuse tests::{expect_frames}; This first line is the SoftNpu implementation that lives in the test crate of the oxidecomputer/p4 repository. The second is a helper macro that allows us to make assertions about frames coming from a SoftNpu \"physical\" port (referred to as a phy). The next line is using the x4c compiler to translate P4 code into Rust code and dumping that Rust code into our program. The macro literally expands into the Rust code emitted by the compiler for the specified P4 source file. p4_macro::use_p4!(p4 = \"book/code/src/bin/hello-world.p4\", pipeline_name = \"hello\"); The main artifact this produces is a Rust struct called main_pipeline which is used in the code that comes next. let pipeline = main_pipeline::new(2);\nlet mut npu = SoftNpu::new(2, pipeline, false);\nlet phy1 = npu.phy(0);\nlet phy2 = npu.phy(1); This code is instantiating a pipeline object that encapsulates the logic of our P4 program. Then a SoftNpu ASIC is constructed with two ports and our pipeline program. SoftNpu objects provide a phy method that takes a port index to get a reference to a port that is attached to the ASIC. These port objects are used to send and receive packets through the ASIC, which uses our compiled P4 code to process those packets. Next we run our program on the SoftNpu ASIC. npu.run(); However, this does not actually do anything until we pass some packets through it, so lets do that. phy1.send(&[TxFrame::new(phy2.mac, 0, b\"hello\")])?; This code transmits an Ethernet frame through the first port of the ASIC with a payload value of \"hello\". The phy2.mac parameter of the TxFrame sets the destination MAC address and the 0 for the second parameter is the ethertype used in the outgoing Ethernet frame. Based on the logic in our P4 program, we would expect this packet to come out the second port. Let's test that. expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b\"hello\")]); This code reads a packet from the second ASIC port phy2 (blocking until there is a packet available) and asserts the following. The Ethernet payload is the byte string \"hello\". The source MAC address is that of phy1. The ethertype is 0. To complete the hello world program, we do the same thing in the opposite direction. Sending the byte string \"world\" as an Ethernet payload into port 2 and assert that it comes out port 1. phy2.send(&[TxFrame::new(phy1.mac, 0, b\"world\")])?;\nexpect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b\"world\")]); The expect_frames macro will also print payloads and the port they came from. When we run this program we see the following. $ cargo run --bin hello-world Compiling x4c-book v0.1.0 (/home/ry/src/p4/book/code) Finished dev [unoptimized + debuginfo] target(s) in 2.05s Running `target/debug/hello-world`\n[phy2] hello\n[phy1] world","breadcrumbs":"The Basics » Compile and Run » Compile and Run","id":"13","title":"Compile and Run"},"14":{"body":"The example above shows using x4c compiled code is a setting that is only really useful for testing the logic of compiled pipelines and demonstrating how P4 and x4c compiled pipelines work. This begs the question of what the target use cases for x4c actually are. It also raises question, why build x4c in the first place? Why not use the established reference compiler p4c and its associated reference behavioral model bmv2? A key difference between x4c and the p4c ecosystem is how compilation and execution concerns are separated. x4c generates free-standing pipelines that can be used by other code, p4c generates JSON that is interpreted and run by bmv2 . The example above shows how the generation of free-standing runnable pipelines can be used to test the logic of P4 programs in a lightweight way. We went from P4 program source to actual packet processing using nothing but the Rust compiler and package manager. The program is executable in an operating system independent way and is a great way to get CI going for P4 programs. The free-standing pipeline approach is not limited to self-contained use cases with packets that are generated and consumed in-program. x4c generated code conforms to a well defined Pipeline interface that can be used to run pipelines anywhere rustc compiled code can run. Pipelines are even dynamically loadable through dlopen and the like. The x4c authors have used x4c generated pipelines to create virtual ASICs inside hypervisors that transit real traffic between virtual machines, as well as P4 programs running inside zones/containers that implement NAT and tunnel encap/decap capabilities. The mechanics of I/O are deliberately outside the scope of x4c generated code. Whether you want to use DLPI, XDP, libpcap, PF_RING, DPDK, etc., is up to you and the harness code you write around your pipelines! The win with x4c is flexibility. You can compile a free-standing P4 pipeline and use that pipeline wherever you see fit. The near-term use for x4c focuses on development and evaluation environments. If you are building a system around P4 programmable components, but it's not realistic to buy all the switches/routers/ASICs at the scale you need for testing/development, x4c is an option. x4c is also a good option for running packets through your pipelines in a lightweight way in CI.","breadcrumbs":"The Basics » Compile and Run » SoftNpu and Target x4c Use Cases.","id":"14","title":"SoftNpu and Target x4c Use Cases."},"15":{"body":"This chapter presents the use of the P4 language and x4c through a series of examples. This is a living set that will grow over time.","breadcrumbs":"By Example » By Example","id":"15","title":"By Example"},"16":{"body":"This example presents a simple VLAN switch program. This program allows a single VLAN id (vid) to be set per port. Any packet arriving at a port with a vid set must carry that vid in its Ethernet header or it will be dropped. We'll refer to this as VLAN filtering. If a packet makes it past ingress filtering, then the forwarding table of the switch is consulted to see what port to send the packet out. We limit ourselves to a very simple switch here with a static forwarding table. A MAC learning switch will be presented in a later example. This switch also does not do flooding for unknown packets, it simply operates on the lookup table it has. If an egress port is identified via a forwarding table lookup, then egress VLAN filtering is applied. If the vid on the packet is present on the egress port then the packet is forwarded out that port. This example is comprised of two programs. A P4 data-plane program and a Rust control-plane program.","breadcrumbs":"By Example » VLAN Switch » VLAN Switch","id":"16","title":"VLAN Switch"},"17":{"body":"Let's start by taking a look at the headers for the P4 program. header ethernet_h { bit<48> dst; bit<48> src; bit<16> ether_type;\n} header vlan_h { bit<3> pcp; bit<1> dei; bit<12> vid; bit<16> ether_type;\n} struct headers_t { ethernet_h eth; vlan_h vlan;\n} An Ethernet frame is normally just 14 bytes with a 6 byte source and destination plus a two byte ethertype. However, when VLAN tags are present the ethertype is set to 0x8100 and a VLAN header follows. This header contains a 12-bit vid as well as an ethertype for the header that follows. A byte-oriented packet diagram shows how these two Ethernet frame variants line up. 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8\n+---------------------------+\n| src | dst |et |\n+---------------------------+\n+-----------------------------------+\n| src | dst |et |pdv|et |\n+------------------------------------ The structure is always the same for the first 14 bytes. So we can take advantage of that when parsing any type of Ethernet frame. Then we can use the ethertype field to determine if we are looking at a regular Ethernet frame or a VLAN-tagged Ethernet frame. parser parse ( packet_in pkt, out headers_t h, inout ingress_metadata_t ingress,\n) { state start { pkt.extract(h.eth); if (h.eth.ether_type == 16w0x8100) { transition vlan; } transition accept; } state vlan { pkt.extract(h.vlan); transition accept; }\n} This parser does exactly what we described above. First parse the first 14 bytes of the packet as an Ethernet frame. Then conditionally parse the VLAN portion of the Ethernet frame if the ethertype indicates we should do so. In a sense we can think of the VLAN portion of the Ethernet frame as being it's own independent header. We are keying our decisions based on the ethertype, just as we would for layer 3 protocol headers. Our VLAN switch P4 program is broken up into multiple control blocks. We'll start with the top level control block and then dive into the control blocks it calls into to implement the switch. control ingress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { vlan() vlan; forward() fwd; apply { bit<12> vid = 12w0; if (hdr.vlan.isValid()) { vid = hdr.vlan.vid; } // check vlan on ingress bool vlan_ok = false; vlan.apply(ingress.port, vid, vlan_ok); if (vlan_ok == false) { egress.drop = true; return; } // apply switch forwarding logic fwd.apply(hdr, egress); // check vlan on egress vlan.apply(egress.port, vid, vlan_ok); if (vlan_ok == false) { egress.drop = true; return; } }\n} The first thing that is happening in this program is the instantiation of a few other control blocks. vlan() vlan;\nforward() fwd; We'll be using these control blocks to implement the VLAN filtering and switch forwarding logic. For now let's take a look at the higher level packet processing logic of the program in the apply block. The first thing we do is start by assuming there is no vid by setting it to zero. The if the VLAN header is valid we assign the vid from the packet header to our local vid variable. The isValid header method returns true if extract was called on that header. Recall from the parser code above, that extract is only called on hdr.vlan if the ethertype on the Ethernet frame is 0x1800. bit<12> vid = 12w0;\nif (hdr.vlan.isValid()) { vid = hdr.vlan.vid;\n} Next apply VLAN filtering logic. First an indicator variable vlan_ok is initialized to false. Then we pass that indicator variable along with the port the packet came in on and the vid we determined above to the VLAN control block. bool vlan_ok = false;\nvlan.apply(ingress.port, vid, vlan_ok);\nif (vlan_ok == false) { egress.drop = true; return;\n} Let's take a look at the VLAN control block. The first thing to note here is the direction of parameters. The port and vid parameters are in parameters, meaning that the control block can only read from them. The match parameter is an out parameter meaning the control block can only write to it. Consider this in the context of the code above. There we are passing in the vlan_ok to the control block with the expectation that the control block will modify the value of the variable. The out direction of this control block parameter is what makes that possible. control vlan( in bit<16> port, in bit<12> vid, out bool match,\n) { action no_vid_for_port() { match = true; } action filter(bit<12> port_vid) { if (port_vid == vid) { match = true; } } table port_vlan { key = { port: exact; } actions = { no_vid_for_port; filter; } default_action = no_vid_for_port; } apply { port_vlan.apply(); }\n} Let's look at this control block starting from the table declaration. The port_vlan table has the port id as the single key element. There are two possible actions no_vid_for_port and filter. The no_vid_for_port fires when there is no match for the port id. That action unconditionally sets match to true. The logic here is that if there is no VLAN configure for a port e.g., the port is not in the table, then there is no need to do any VLAN filtering and just pass the packet along. The filter action takes a single parameter port_vid. This value is populated by the table value entry corresponding to the port key. There are no static table entries in this P4 program, they are provided by a control plane program which we'll get to in a bit. The filter logic tests if the port_vid that has been configured by the control plane matches the vid on the packet. If the test passes then match is set to true meaning the packet can continue processing. Popping back up to the top level control block. If vlan_ok was not set to true in the vlan control block, then we drop the packet. Otherwise we continue on to further processing - forwarding. Here we are passing the entire header and egress metadata structures into the fwd control block which is an instantiation of the forward control block type. fwd.apply(hdr, egress); Lets take a look at the forward control block. control forward( inout headers_t hdr, inout egress_metadata_t egress,\n) { action drop() {} action forward(bit<16> port) { egress.port = port; } table fib { key = { hdr.eth.dst: exact; } actions = { drop; forward; } default_action = drop; } apply { fib.apply(); }\n} This simple control block contains a table that maps Ethernet addresses to ports. The single element key contains an Ethernet destination and the matching action forward contains a single 16-bit port value. When the Ethernet destination matches an entry in the table, the egress metadata destination for the packet is set to the port id that has been set for that table entry. Note that in this control block both parameters have an inout direction, meaning the control block can both read from and write to these parameters. Like the vlan control block above, there are no static entries here. Entries for the table in this control block are filled in by a control-plane program. Popping back up the stack to our top level control block, the remaining code we have is the following. vlan.apply(egress.port, vid, vlan_ok);\nif (vlan_ok == false) { egress.drop = true; return;\n} This is pretty much the same as what we did at the beginning of the apply block. Except this time, we are passing in the egress port instead of the ingress port. We are checking the VLAN tags not only for the ingress port, but also for the egress port. You can find this program in it's entirety here .","breadcrumbs":"By Example » VLAN Switch » P4 Data-Plane Program","id":"17","title":"P4 Data-Plane Program"},"18":{"body":"The main purpose of the Rust control plane program is to manage table entries in the P4 program. In addition to table management, the program we'll be showing here also instantiates and runs the P4 code over a virtual ASIC to demonstrate the complete system working. We'll start top down again. Here is the beginning of our Rust program. use tests::expect_frames;\nuse tests::softnpu::{RxFrame, SoftNpu, TxFrame}; p4_macro::use_p4!( p4 = \"book/code/src/bin/vlan-switch.p4\", pipeline_name = \"vlan_switch\"\n); fn main() -> Result<(), anyhow::Error> { let mut pipeline = main_pipeline::new(2); let m1 = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33]; let m2 = [0x44, 0x44, 0x44, 0x44, 0x44, 0x44]; init_tables(&mut pipeline, m1, m2); run_test(pipeline, m2)\n} After imports, the first thing we are doing is calling the use_p4! macro. This translates our P4 program into Rust and expands the use_p4! macro in place to the generated Rust code. This results in the main_pipeline type that we see instantiated in the first line of the main program. Then we define a few MAC addresses that we'll get back to later. The remainder of the main code performs the two functions described above. The init_tables function acts as a control plane for our P4 code, setting up the VLAN and forwarding tables. The run_test code executes our instantiated pipeline over a virtual ASIC, sends some packets through it, and makes assertions about the results.","breadcrumbs":"By Example » VLAN Switch » Rust Control-Plane Program","id":"18","title":"Rust Control-Plane Program"},"19":{"body":"Let's jump into the control plane code. fn init_tables(pipeline: &mut main_pipeline, m1: [u8;6], m2: [u8;6]) { // add static forwarding entries pipeline.add_ingress_fwd_fib_entry(\"forward\", &m1, &0u16.to_be_bytes()); pipeline.add_ingress_fwd_fib_entry(\"forward\", &m2, &1u16.to_be_bytes()); // port 0 vlan 47 pipeline.add_ingress_vlan_port_vlan_entry( \"filter\", 0u16.to_be_bytes().as_ref(), 47u16.to_be_bytes().as_ref(), ); // sanity check the table let x = pipeline.get_ingress_vlan_port_vlan_entries(); println!(\"{:#?}\", x); // port 1 vlan 47 pipeline.add_ingress_vlan_port_vlan_entry( \"filter\", 1u16.to_be_bytes().as_ref(), 47u16.to_be_bytes().as_ref(), ); } The first thing that happens here is the forwarding tables are set up. We add two entries one for each MAC address. The first MAC address maps to the first port and the second MAC address maps to the second port. We are using table modification methods from the Rust code that was generated from our P4 code. A valid question is, how do I know what these are? There are two ways. Determine Based on P4 Code Structure The naming is deterministic based on the structure of the p4 program. Table modification functions follow the pattern ___entry. Where operation one of the following. add remove get. The control_path is based on the names of control instances starting from the top level ingress controller. In our P4 program, the forwarding table is named fwd so that is what we see in the function above. If there is a longer chain of controller instances, the instance names are underscore separated. Finally the table_name is the name of the table in the control block. This is how we arrive at the method name above. pipeline.add_fwd_fib_entry(...) Use cargo doc Alternatively you can just run cargo doc to have Cargo generate documentation for your crate that contains the P4-generated Rust code. This will emit Rust documentation that includes documentation for the generated code. Now back to the control plane code above. You'll also notice that we are adding key values and parameter values to the P4 tables as byte slices. At the time of writing, x4c is not generating high-level table manipulation APIs so we have to pass everything in as binary serialized data. The semantics of these data buffers are the following. Both key data and match action data (parameters) are passed in in-order. Numeric types are serialized in big-endian byte order. If a set of keys or a set of parameters results in a size that does not land on a byte-boundary, i.e. 12 bytes like we have in this example, the length of the buffer is rounded up to the nearest byte boundary. After adding the forwarding entries, VLAN table entries are added in the same manner. A VLAN with the vid of 47 is added to the first and second ports. Note that we also use a table access method to get all the entries of a table and print them out to convince ourselves our code is doing what we intend.","breadcrumbs":"By Example » VLAN Switch » Control Plane Code","id":"19","title":"Control Plane Code"},"2":{"body":"","breadcrumbs":"The Basics » Installation » Installation","id":"2","title":"Installation"},"20":{"body":"Now let's take a look at the test portion of our code. fn run_test( pipeline: main_pipeline, m2: [u8; 6], m3: [u8; 6],\n) -> Result<(), anyhow::Error> { // create and run the softnpu instance let mut npu = SoftNpu::new(2, pipeline, false); let phy1 = npu.phy(0); let phy2 = npu.phy(1); npu.run(); // send a packet we expect to make it through phy1.send(&[TxFrame::newv(m2, 0, b\"blueberry\", 47)])?; expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b\"blueberry\", 47)]); // send 3 packets, we expect the first 2 to get filtered by vlan rules phy1.send(&[TxFrame::newv(m2, 0, b\"poppyseed\", 74)])?; // 74 != 47 phy1.send(&[TxFrame::new(m2, 0, b\"banana\")])?; // no tag phy1.send(&[TxFrame::newv(m2, 0, b\"muffin\", 47)])?; phy1.send(&[TxFrame::newv(m3, 0, b\"nut\", 47)])?; // no forwarding entry expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b\"muffin\", 47)]); Ok(())\n} The first thing we do here is create a SoftNpu virtual ASIC instance with 2 ports that will execute the pipeline we configured with entries in the previous section. We get references to each ASIC port and run the ASIC. Next we send a few packets through the ASIC to validate that our P4 program is doing what we expect given how we have configured the tables. The first test passes through a packet we expect to make it through the VLAN filtering. The next test sends 4 packets in the ASIC, but we expect our P4 program to filter 3 of them out. The first packet has the wrong vid. The second packet has no vid. The third packet should make it through. The fourth packet has no forwarding entry. Running the test When we run this program we see the following $ cargo run --bin vlan-switch Finished dev [unoptimized + debuginfo] target(s) in 0.11s Running `target/debug/vlan-switch`\n[ TableEntry { action_id: \"filter\", keyset_data: [ 0, 0, ], parameter_data: [ 0, 47, ], },\n]\n[phy2] blueberry\ndrop\ndrop\ndrop\n[phy2] muffin The first thing we see is our little sanity check dumping out the VLAN table after adding a single entry. This has what we expect, mapping the port 0 to the vid 47. Next we start sending packets through the ASIC. There are two frame constructors in play here. TxFrame::newv creates an Ethernet frame with a VLAN header and TxFrame::new creates just a plane old Ethernet frame. The first argument to each frame constructor is the destination MAC address. The second argument is the ethertype to use and the third argument is the Ethernet payload. Next we see that our blueberry packet made it through as expected. Then we see three packets getting dropped as we expect. And finally we see the muffin packet coming through as expected. You can find this program in it's entirety here .","breadcrumbs":"By Example » VLAN Switch » Test Code","id":"20","title":"Test Code"},"21":{"body":"Ths chapter provides guidelines on various aspects of the x4c compiler.","breadcrumbs":"Guidelines » Guidelines","id":"21","title":"Guidelines"},"22":{"body":"The basic rules for endianness follow. Generally speaking numeric fields are in big endian when they come in off the wire, little endian while in the program, and transformed back to big endian on the way back out onto the wire. We refer to this as confused endian. All numeric packet field data is big endian when enters and leaves a p4 program. All numeric data, including packet fields is little endian inside a p4 program. Table keys with the exact and range type defined over bit types are in little endian. Table keys with the lpm type are in the byte order they appear on the wire.","breadcrumbs":"Guidelines » Endianness » Endianness","id":"22","title":"Endianness"},"3":{"body":"The first thing we'll need to do is install Rust. We'll be using a tool called rustup . On Unix/Linux like platforms, simply run the following from your terminal. For other platforms see the rustup docs. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh It may be necessary to restart your shell session after installing Rust.","breadcrumbs":"The Basics » Installation » Rust","id":"3","title":"Rust"},"4":{"body":"Now we will install the x4c compiler using the rust cargo tool. cargo install --git https://github.com/oxidecomputer/p4 x4c You should now be able to run x4c. x4c --help\nx4c 0.1 USAGE: x4c [OPTIONS] [TARGET] ARGS: File to compile What target to generate code for [default: rust] [possible values: rust, red-hawk, docs] OPTIONS: --check Just check code, do not compile -h, --help Print help information -o, --out Filename to write generated code to [default: out.rs] --show-ast Show parsed abstract syntax tree --show-hlir Show high-level intermediate representation info --show-pre Show parsed preprocessor info --show-tokens Show parsed lexical tokens -V, --version Print version information That's it! We're now ready to dive into P4 code.","breadcrumbs":"The Basics » Installation » x4c","id":"4","title":"x4c"},"5":{"body":"Let's start out our introduction of P4 with the obligatory hello world program.","breadcrumbs":"The Basics » Hello World » Hello World","id":"5","title":"Hello World"},"6":{"body":"The first bit of programmable logic packets hit in a P4 program is a parser. Parsers do the following. Describe a state machine packet parsing. Extract raw data into headers with typed fields. Decide if a packet should be accepted or rejected based on parsed structure. In the code below, we can see that parsers are defined somewhat like functions in general-purpose programming languages. They take a set of parameters and have a curly-brace delimited block of code that acts over those parameters. Each of the parameters has an optional direction that we see here as out or inout, a type, and a name. We'll get to data types in the next section for now let's focus on what this parser code is doing. The parameters shown here are typical of what you will see for P4 parsers. The exact set of parameters varies depending on ASIC the P4 code is being compiled for. But in general, there will always need to be - a packet, set of headers to extract packet data into and a bit of metadata about the packet that the ASIC has collected. parser parse ( packet_in pkt, out headers_t headers, inout ingress_metadata_t ingress,\n){ state start { pkt.extract(headers.ethernet); transition finish; } state finish { transition accept; }\n} Parsers are made up of a set of states and transitions between those states. Parsers must always include a start state . Our start state extracts an Ethernet header from the incoming packet and places it in to the headers_t parameter passed to the parser. We then transition to the finish state where we simply transition to the implicit accept state. We could have just transitioned to accept from start, but wanted to show transitions between user-defined states in this example. Transitioning to the accept state means that the packet will be passed to a control block for further processing. Control blocks will be covered a few sections from now. Parsers can also transition to the implicit reject state. This means that the packet will be dropped and not go on to any further processing.","breadcrumbs":"The Basics » Hello World » Parsing","id":"6","title":"Parsing"},"7":{"body":"There are two primary data types in P4, struct and header types.","breadcrumbs":"The Basics » Hello World » Data Types","id":"7","title":"Data Types"},"8":{"body":"Structs in P4 are similar to structs you'll find in general purpose programming languages such as C, Rust, and Go. They are containers for data with typed data fields. They can contain basic data types, headers as well as other structs. Let's take a look at the structs in use by our hello world program. The first is a structure containing headers for our program to extract packet data into. This headers_t structure is simple and only contains one header. However, there may be an arbitrary number of headers in the struct. We'll discuss headers in the next section. struct headers_t { ethernet_t ethernet;\n} The next structure is a bit of metadata provided to our parser by the ASIC. In our simple example this just includes the port that the packet came from. So if our code is running on a four port switch, the port field would take on a value between 0 and 3 depending on which port the packet came in on. struct ingress_metadata_t { bit<16> port;\n} As the name suggests bit<16> is a 16-bit value. In P4 the bit type commonly represents unsigned integer values. We'll get more into the primitive data types of P4 later.","breadcrumbs":"The Basics » Hello World » Structs","id":"8","title":"Structs"},"9":{"body":"Headers are the result of parsing packets. They are similar in nature to structures with the following differences. Headers may not contain headers. Headers have a set of methods isValid(), setValid(), and setValid() that provide a means for parsers and control blocks to coordinate on the parsed structure of packets as they move through pipelines. Let's take a look at the ethernet_h header in our hello world example. header ethernet_h { bit<48> dst; bit<48> src; bit<16> ether_type;\n} This header represents a layer-2 Ethernet frame . The leading octet is not present as this will be removed by most ASICs. What remains is the MAC source and destination fields which are each 6 octets / 48 bits and the ethertype which is 2 octets. Note also that the payload is not included here. This is important. P4 programs typically operate on packet headers and not packet payloads. In upcoming examples we'll go over header stacks that include headers at higher layers like IP, ICMP and TCP. In the parsing code above, when pkt.extract(headers.ethernet) is called, the values dst, src and ether_type are populated from packet data and the method setValid() is implicitly called on the headers.ethernet header.","breadcrumbs":"The Basics » Hello World » Headers","id":"9","title":"Headers"}},"length":23,"save":true},"fields":["title","body","breadcrumbs"],"index":{"body":{"root":{"0":{".":{"1":{"1":{"df":1,"docs":{"20":{"tf":1.0}}},"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":3.1622776601683795},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":3.0},"8":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"x":{"1":{"8":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"4":{"4":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"8":{"1":{"0":{"0":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"2":{"df":2,"docs":{"17":{"tf":1.0},"19":{"tf":1.0}},"w":{"0":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"4":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"6":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.0}},"w":{"0":{"df":2,"docs":{"10":{"tf":2.0},"12":{"tf":1.0}},"x":{"8":{"1":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"19":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"5":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"3":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"4":{"7":{"df":2,"docs":{"19":{"tf":1.7320508075688772},"20":{"tf":2.8284271247461903}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"8":{"df":1,"docs":{"9":{"tf":1.0}}},"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"5":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"6":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"7":{"4":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"8":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"9":{"df":1,"docs":{"17":{"tf":1.0}}},"a":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":6,"docs":{"10":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":4,"docs":{"10":{"tf":3.3166247903554},"12":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"v":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"d":{"df":1,"docs":{"19":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":6,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0}}}}}}},"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.0}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.6457513110645907}}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":1.0},"20":{"tf":1.7320508075688772}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"p":{"df":1,"docs":{"10":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"c":{"df":9,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.4142135623730951},"13":{"tf":2.8284271247461903},"14":{"tf":1.0},"18":{"tf":1.4142135623730951},"20":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}},"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"0":{"tf":1.0},"17":{"tf":1.0}}}}},"t":{"df":1,"docs":{"4":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"b":{"\"":{"b":{"a":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"n":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":2.0}}}}}}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}}},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":5,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"i":{"c":{"df":4,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"22":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.0}},"g":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.0},"18":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"6":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":2.0}}},"6":{"df":4,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.0}}},"3":{"df":1,"docs":{"17":{"tf":1.0}}},"4":{"8":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"17":{"tf":1.7320508075688772},"22":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":7,"docs":{"10":{"tf":4.0},"11":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":5.0990195135927845},"19":{"tf":1.0},"6":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"v":{"2":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951}}},"l":{"df":2,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"a":{"d":{"c":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"y":{"df":1,"docs":{"14":{"tf":1.0}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"19":{"tf":2.23606797749979},"22":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"3":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":4,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.7320508075688772}}}}},"df":1,"docs":{"8":{"tf":1.0}},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"i":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"o":{"d":{"df":0,"docs":{},"e":{"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":3.4641016151377544},"14":{"tf":2.449489742783178},"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"19":{"tf":3.0},"20":{"tf":1.4142135623730951},"4":{"tf":2.0},"6":{"tf":2.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":2.0},"20":{"tf":1.0},"22":{"tf":1.0}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":8,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":2.8284271247461903},"21":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0}}},"x":{"df":1,"docs":{"11":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"11":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":9,"docs":{"10":{"tf":3.605551275463989},"11":{"tf":1.7320508075688772},"12":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":5.477225575051661},"18":{"tf":1.7320508075688772},"19":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"20":{"tf":2.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":9,"docs":{"10":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":2.0},"22":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.4142135623730951},"8":{"tf":2.23606797749979},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":2.0},"14":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}},"i":{"df":1,"docs":{"17":{"tf":1.0}}},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}}},"v":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.0}}}}}}}},"i":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}},"o":{"c":{"df":3,"docs":{"19":{"tf":1.4142135623730951},"3":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}}}}}},"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"p":{"d":{"df":0,"docs":{},"k":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":6,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.449489742783178},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":2.0},"6":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"0":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"6":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":2.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"17":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.7320508075688772},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.23606797749979},"16":{"tf":1.7320508075688772},"17":{"tf":3.0}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"n":{"c":{"a":{"df":0,"docs":{},"p":{"/":{"d":{"df":0,"docs":{},"e":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":3.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"17":{"tf":2.449489742783178},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"20":{"tf":2.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}},"h":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"h":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":3.4641016151377544},"20":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":12,"docs":{"0":{"tf":1.4142135623730951},"10":{"tf":2.6457513110645907},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":1.4142135623730951},"16":{"tf":1.7320508075688772},"19":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0},"20":{"tf":1.0}}}}},"df":0,"docs":{}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"!":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"20":{"tf":3.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":5,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"i":{"b":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"d":{"df":6,"docs":{"10":{"tf":2.0},"17":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"4":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":1,"docs":{"17":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.7320508075688772},"17":{"tf":2.6457513110645907},"19":{"tf":1.4142135623730951},"20":{"tf":2.0}}}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}},"d":{"df":3,"docs":{"17":{"tf":1.0},"20":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.7320508075688772}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":10,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":2.6457513110645907},"18":{"tf":1.4142135623730951},"19":{"tf":2.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"16":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"6":{"tf":1.0}},"s":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":9,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"(":{"1":{"6":{"df":0,"docs":{},"w":{"0":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"1":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"6":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"8":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.7320508075688772},"17":{"tf":3.0},"20":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":2.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.0}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}}}}},"w":{"d":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"h":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":2,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"10":{"tf":2.23606797749979},"14":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"t":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.0},"20":{"tf":1.0}}}}}},"o":{"df":5,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"o":{"d":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"15":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}},"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}}},"r":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"w":{"df":0,"docs":{},"k":{"df":1,"docs":{"4":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"d":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{".":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951}}}},"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":2.0},"12":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":3.605551275463989},"20":{"tf":1.0},"6":{"tf":2.0},"7":{"tf":1.0},"8":{"tf":2.23606797749979},"9":{"tf":3.4641016151377544}},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}},"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":7,"docs":{"1":{"tf":1.4142135623730951},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"5":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"p":{"df":1,"docs":{"4":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":8,"docs":{"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"df":0,"docs":{},"p":{"4":{"/":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.0}},"s":{":":{"/":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"u":{"b":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}}}},"i":{".":{"df":1,"docs":{"19":{"tf":1.0}}},"/":{"df":0,"docs":{},"o":{"df":1,"docs":{"14":{"tf":1.0}}}},"c":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"df":2,"docs":{"16":{"tf":1.0},"17":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.4142135623730951}}}}}}},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"9":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.0},"10":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"14":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}},"x":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"4":{"tf":1.4142135623730951}},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":7,"docs":{"10":{"tf":2.449489742783178},"11":{"tf":1.0},"12":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.0},"6":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.6457513110645907},"17":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"22":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.0},"3":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951}}},"n":{"c":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"8":{"tf":1.0}}},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"a":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"0":{"tf":1.0}},"t":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"c":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"t":{"'":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"y":{"df":6,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"19":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}}},"l":{"a":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":2.23606797749979},"15":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"8":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}},"v":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"t":{"'":{"df":8,"docs":{"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":2,"docs":{"13":{"tf":1.0},"17":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":3,"docs":{"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}}},"i":{"b":{"df":0,"docs":{},"p":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}}}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"l":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"15":{"tf":1.0}}}}},"o":{"a":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":5,"docs":{"10":{"tf":2.0},"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"6":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"k":{"df":6,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"p":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}},"m":{"1":{"df":2,"docs":{"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951}}},"2":{"df":3,"docs":{"18":{"tf":1.7320508075688772},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"a":{"c":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"9":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"18":{"tf":2.0}}}},"k":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"p":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}},"i":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"19":{"tf":2.449489742783178},"6":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":4,"docs":{"14":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}}}}},"x":{"df":0,"docs":{},"t":{"df":6,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"17":{"tf":1.0},"20":{"tf":2.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}},"o":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"9":{"tf":1.0}}},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"(":{"0":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"1":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}},"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}}}}},"d":{"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"4":{"tf":1.0}},"k":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"l":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"n":{"df":5,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"19":{"tf":1.4142135623730951},"8":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"22":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{">":{"_":{"<":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{">":{"_":{"<":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{">":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":4,"docs":{"14":{"tf":1.0},"16":{"tf":1.0},"19":{"tf":1.0},"9":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.4142135623730951},"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"f":{"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}}}},"t":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":11,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"5":{"tf":1.0},"6":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"4":{"_":{"df":0,"docs":{},"m":{"a":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"4":{"!":{"(":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"c":{"df":1,"docs":{"14":{"tf":1.7320508075688772}}},"df":20,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"10":{"tf":2.8284271247461903},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":2.6457513110645907},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":2.23606797749979},"19":{"tf":2.449489742783178},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"4":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}},"a":{"c":{"df":0,"docs":{},"k":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"11":{"tf":2.449489742783178},"14":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"10":{"tf":1.0}}},"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}}},"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":3.872983346207417},"12":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.7320508075688772},"16":{"tf":2.449489742783178},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"20":{"tf":3.605551275463989},"22":{"tf":1.4142135623730951},"6":{"tf":3.0},"8":{"tf":1.7320508075688772},"9":{"tf":2.23606797749979}}}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":3.3166247903554},"13":{"tf":1.4142135623730951},"17":{"tf":3.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.449489742783178}},"e":{"df":0,"docs":{},"r":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"s":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"12":{"tf":1.4142135623730951},"17":{"tf":2.0},"4":{"tf":1.7320508075688772},"6":{"tf":2.0},"9":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":2.6457513110645907},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.1622776601683795},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":7,"docs":{"0":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"6":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":3,"docs":{"13":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}},"d":{"df":0,"docs":{},"v":{"df":0,"docs":{},"|":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"16":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"f":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"h":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"y":{"1":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.7320508075688772}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.0}}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":7,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":3.605551275463989},"18":{"tf":1.7320508075688772},"20":{"tf":1.7320508075688772},"9":{"tf":1.0}},"e":{".":{"a":{"d":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"(":{"\"":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"k":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"18":{"tf":1.7320508075688772},"19":{"tf":1.7320508075688772},"20":{"tf":1.0}}}},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"y":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"p":{"df":1,"docs":{"17":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":2.0}}},"df":0,"docs":{}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":3.0},"12":{"tf":2.449489742783178},"13":{"tf":3.3166247903554},"16":{"tf":2.449489742783178},"17":{"tf":4.242640687119285},"19":{"tf":2.23606797749979},"20":{"tf":1.7320508075688772},"8":{"tf":2.23606797749979}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"4":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"o":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":17,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"10":{"tf":4.123105625617661},"11":{"tf":1.0},"12":{"tf":2.0},"13":{"tf":3.7416573867739413},"14":{"tf":2.449489742783178},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.6457513110645907},"19":{"tf":1.4142135623730951},"20":{"tf":2.0},"22":{"tf":1.7320508075688772},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":2.0},"17":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":7,"docs":{"0":{"tf":1.0},"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.0},"21":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":4,"docs":{"10":{"tf":2.0},"18":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"1":{"tf":1.0}}}},"t":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"19":{"tf":1.0}}}}}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.4142135623730951}},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"16":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"19":{"tf":1.0},"9":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"18":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":1,"docs":{"10":{"tf":2.23606797749979}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.0}}}},"n":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}}},"df":2,"docs":{"18":{"tf":1.0},"20":{"tf":1.0}}}}}}},"df":10,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":2.23606797749979},"19":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"4":{"tf":1.7320508075688772},"8":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"s":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}}}}},"w":{"df":1,"docs":{"10":{"tf":1.0}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":2.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":2.0},"20":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":8,"docs":{"13":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.23606797749979},"3":{"tf":1.0},"6":{"tf":1.7320508075688772}}},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"14":{"tf":1.0}}}},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"d":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"16":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.23606797749979}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"14":{"tf":1.0},"19":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}},"df":1,"docs":{"15":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"t":{"df":11,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"4":{"tf":2.8284271247461903},"6":{"tf":1.0}},"n":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":2.0},"16":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}},"i":{"df":3,"docs":{"16":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0}}}}},"z":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":6,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":3.0},"14":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"22":{"tf":1.0}}}},"c":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0}}}}}},"df":0,"docs":{}}},"r":{"c":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"f":{"df":1,"docs":{"3":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":2.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":8,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":2.0}}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"6":{"tf":3.4641016151377544}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":2.8284271247461903}},"u":{"df":0,"docs":{},"r":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":4,"docs":{"16":{"tf":2.449489742783178},"17":{"tf":2.0},"20":{"tf":1.4142135623730951},"8":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"/":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0}}}}}}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":8,"docs":{"10":{"tf":4.69041575982343},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.3166247903554},"18":{"tf":1.7320508075688772},"19":{"tf":3.3166247903554},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951}},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.0}}},"k":{"df":0,"docs":{},"e":{"df":9,"docs":{"1":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"/":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.4142135623730951},"4":{"tf":1.7320508075688772}}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"10":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"l":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"20":{"tf":2.23606797749979}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"{":{"df":0,"docs":{},"r":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"{":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"3":{"tf":1.0}}},"k":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"d":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.0},"14":{"tf":1.4142135623730951},"15":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.8284271247461903},"9":{"tf":1.0}}}}}}}},"i":{"df":1,"docs":{"11":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"1":{".":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"l":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":2,"docs":{"3":{"tf":1.0},"4":{"tf":1.0}}}},"p":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.0}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{"df":1,"docs":{"17":{"tf":3.1622776601683795}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"o":{"df":8,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"7":{"tf":1.0}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"20":{"tf":1.0}},"v":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"8":{"tf":2.0}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"8":{";":{"6":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"/":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"k":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}},"p":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":13,"docs":{"0":{"tf":1.7320508075688772},"10":{"tf":2.23606797749979},"12":{"tf":1.4142135623730951},"13":{"tf":3.1622776601683795},"14":{"tf":3.7416573867739413},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"v":{"0":{".":{"1":{".":{"0":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":7,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":2.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":1,"docs":{"6":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":1,"docs":{"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"16":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}}}}},"i":{"a":{"df":1,"docs":{"16":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}}}},"d":{"df":4,"docs":{"16":{"tf":2.0},"17":{"tf":4.242640687119285},"19":{"tf":1.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"df":0,"docs":{}}}}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"17":{"tf":3.605551275463989}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"16":{"tf":2.23606797749979},"17":{"tf":5.0990195135927845},"18":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":2.23606797749979}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}},"y":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":2.0},"19":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":10,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}},"l":{"d":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":7,"docs":{"1":{"tf":1.4142135623730951},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.449489742783178},"5":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":6,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"4":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"x":{"4":{"c":{"df":8,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":3.872983346207417},"15":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"4":{"tf":2.6457513110645907}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"19":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"1":{"tf":1.0},"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"breadcrumbs":{"root":{"0":{".":{"1":{"1":{"df":1,"docs":{"20":{"tf":1.0}}},"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":3.1622776601683795},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":3.0},"8":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"x":{"1":{"8":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"4":{"4":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"8":{"1":{"0":{"0":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"2":{"df":2,"docs":{"17":{"tf":1.0},"19":{"tf":1.0}},"w":{"0":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"4":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"6":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.0}},"w":{"0":{"df":2,"docs":{"10":{"tf":2.0},"12":{"tf":1.0}},"x":{"8":{"1":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"19":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"5":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"3":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"4":{"7":{"df":2,"docs":{"19":{"tf":1.7320508075688772},"20":{"tf":2.8284271247461903}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"8":{"df":1,"docs":{"9":{"tf":1.0}}},"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"5":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"6":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"7":{"4":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"8":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"9":{"df":1,"docs":{"17":{"tf":1.0}}},"a":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":6,"docs":{"10":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":4,"docs":{"10":{"tf":3.3166247903554},"12":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"v":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"d":{"df":1,"docs":{"19":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":6,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0}}}}}}},"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.0}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.6457513110645907}}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":1.0},"20":{"tf":1.7320508075688772}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"p":{"df":1,"docs":{"10":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"c":{"df":9,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.4142135623730951},"13":{"tf":2.8284271247461903},"14":{"tf":1.0},"18":{"tf":1.4142135623730951},"20":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}},"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"0":{"tf":1.0},"17":{"tf":1.0}}}}},"t":{"df":1,"docs":{"4":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"b":{"\"":{"b":{"a":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"n":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":2.0}}}}}}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}}},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":5,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"i":{"c":{"df":16,"docs":{"0":{"tf":1.0},"1":{"tf":1.7320508075688772},"10":{"tf":1.0},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.0}},"g":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.0},"18":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"6":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":2.0}}},"6":{"df":4,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.0}}},"3":{"df":1,"docs":{"17":{"tf":1.0}}},"4":{"8":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"17":{"tf":1.7320508075688772},"22":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":7,"docs":{"10":{"tf":4.123105625617661},"11":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":5.0990195135927845},"19":{"tf":1.0},"6":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"v":{"2":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":2.23606797749979},"13":{"tf":1.4142135623730951}}},"l":{"df":2,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"a":{"d":{"c":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"y":{"df":1,"docs":{"14":{"tf":1.0}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"19":{"tf":2.23606797749979},"22":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"3":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":4,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":2.0}}}}},"df":1,"docs":{"8":{"tf":1.0}},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"i":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"o":{"d":{"df":0,"docs":{},"e":{"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":3.4641016151377544},"14":{"tf":2.449489742783178},"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"19":{"tf":3.1622776601683795},"20":{"tf":1.7320508075688772},"4":{"tf":2.0},"6":{"tf":2.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":2.0},"20":{"tf":1.0},"22":{"tf":1.0}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":8,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":3.0},"21":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0}}},"x":{"df":1,"docs":{"11":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"11":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":9,"docs":{"10":{"tf":3.7416573867739413},"11":{"tf":1.7320508075688772},"12":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":5.477225575051661},"18":{"tf":2.0},"19":{"tf":2.8284271247461903},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"20":{"tf":2.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":9,"docs":{"10":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":2.0},"22":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"8":{"tf":2.23606797749979},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":2.0},"14":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}},"i":{"df":1,"docs":{"17":{"tf":1.0}}},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}}},"v":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.0}}}}}}}},"i":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}},"o":{"c":{"df":3,"docs":{"19":{"tf":1.4142135623730951},"3":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}}}}}},"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"p":{"d":{"df":0,"docs":{},"k":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":6,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.449489742783178},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":2.0},"6":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"0":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"6":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":2.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"17":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.7320508075688772},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.23606797749979},"16":{"tf":1.7320508075688772},"17":{"tf":3.0}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"n":{"c":{"a":{"df":0,"docs":{},"p":{"/":{"d":{"df":0,"docs":{},"e":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":3.3166247903554}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"17":{"tf":2.449489742783178},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"20":{"tf":2.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}},"h":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"h":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":3.4641016151377544},"20":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":15,"docs":{"0":{"tf":1.4142135623730951},"10":{"tf":2.6457513110645907},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.0},"16":{"tf":2.0},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0},"20":{"tf":1.0}}}}},"df":0,"docs":{}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"!":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"20":{"tf":3.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":5,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"i":{"b":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"d":{"df":6,"docs":{"10":{"tf":2.0},"17":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"4":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":1,"docs":{"17":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.7320508075688772},"17":{"tf":2.6457513110645907},"19":{"tf":1.4142135623730951},"20":{"tf":2.0}}}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}},"d":{"df":3,"docs":{"17":{"tf":1.0},"20":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.7320508075688772}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":10,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":2.6457513110645907},"18":{"tf":1.4142135623730951},"19":{"tf":2.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"16":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"6":{"tf":1.0}},"s":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":9,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"(":{"1":{"6":{"df":0,"docs":{},"w":{"0":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"1":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"6":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"8":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.7320508075688772},"17":{"tf":3.0},"20":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":2.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.4142135623730951}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}}}}},"w":{"d":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"h":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":2,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"10":{"tf":2.23606797749979},"14":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"t":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.0},"20":{"tf":1.0}}}}}},"o":{"df":5,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"o":{"d":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"15":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"21":{"tf":2.0},"22":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}},"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}}},"r":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"w":{"df":0,"docs":{},"k":{"df":1,"docs":{"4":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"d":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{".":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951}}}},"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":2.0},"12":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":3.605551275463989},"20":{"tf":1.0},"6":{"tf":2.0},"7":{"tf":1.0},"8":{"tf":2.23606797749979},"9":{"tf":3.605551275463989}},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}},"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":10,"docs":{"1":{"tf":1.4142135623730951},"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.8284271247461903},"5":{"tf":2.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}},"p":{"df":1,"docs":{"4":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":8,"docs":{"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"df":0,"docs":{},"p":{"4":{"/":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.0}},"s":{":":{"/":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"u":{"b":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}}}},"i":{".":{"df":1,"docs":{"19":{"tf":1.0}}},"/":{"df":0,"docs":{},"o":{"df":1,"docs":{"14":{"tf":1.0}}}},"c":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"df":2,"docs":{"16":{"tf":1.0},"17":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.4142135623730951}}}}}}},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"9":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.0},"10":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"14":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}},"x":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"4":{"tf":1.4142135623730951}},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":7,"docs":{"10":{"tf":2.449489742783178},"11":{"tf":1.0},"12":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.0},"6":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.6457513110645907},"17":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"22":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"4":{"tf":1.7320508075688772}}},"n":{"c":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"8":{"tf":1.0}}},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"a":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"0":{"tf":1.0}},"t":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"c":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"t":{"'":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"y":{"df":6,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"19":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}}},"l":{"a":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":2.23606797749979},"15":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"8":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}},"v":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"t":{"'":{"df":8,"docs":{"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":2,"docs":{"13":{"tf":1.0},"17":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":3,"docs":{"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}}},"i":{"b":{"df":0,"docs":{},"p":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}}}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"l":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"15":{"tf":1.0}}}}},"o":{"a":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":5,"docs":{"10":{"tf":2.0},"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"6":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"k":{"df":6,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"p":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}},"m":{"1":{"df":2,"docs":{"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951}}},"2":{"df":3,"docs":{"18":{"tf":1.7320508075688772},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"a":{"c":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"9":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"18":{"tf":2.0}}}},"k":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"p":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}},"i":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"19":{"tf":2.449489742783178},"6":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":4,"docs":{"14":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}}}}},"x":{"df":0,"docs":{},"t":{"df":6,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"17":{"tf":1.0},"20":{"tf":2.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}},"o":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"9":{"tf":1.0}}},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"(":{"0":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"1":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}},"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}}}}},"d":{"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"4":{"tf":1.0}},"k":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"l":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"n":{"df":5,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"19":{"tf":1.4142135623730951},"8":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"22":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{">":{"_":{"<":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{">":{"_":{"<":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{">":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":4,"docs":{"14":{"tf":1.0},"16":{"tf":1.0},"19":{"tf":1.0},"9":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.4142135623730951},"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"f":{"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}}}},"t":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":11,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"5":{"tf":1.0},"6":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"4":{"_":{"df":0,"docs":{},"m":{"a":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"4":{"!":{"(":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"c":{"df":1,"docs":{"14":{"tf":1.7320508075688772}}},"df":20,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"10":{"tf":2.8284271247461903},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":2.6457513110645907},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":2.23606797749979},"19":{"tf":2.449489742783178},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"4":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}},"a":{"c":{"df":0,"docs":{},"k":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"11":{"tf":2.6457513110645907},"14":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"10":{"tf":1.0}}},"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}}},"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":3.872983346207417},"12":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.7320508075688772},"16":{"tf":2.449489742783178},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"20":{"tf":3.605551275463989},"22":{"tf":1.4142135623730951},"6":{"tf":3.0},"8":{"tf":1.7320508075688772},"9":{"tf":2.23606797749979}}}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":3.3166247903554},"13":{"tf":1.4142135623730951},"17":{"tf":3.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.449489742783178}},"e":{"df":0,"docs":{},"r":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"s":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"12":{"tf":1.4142135623730951},"17":{"tf":2.0},"4":{"tf":1.7320508075688772},"6":{"tf":2.23606797749979},"9":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":2.6457513110645907},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.1622776601683795},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":7,"docs":{"0":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"6":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":3,"docs":{"13":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}},"d":{"df":0,"docs":{},"v":{"df":0,"docs":{},"|":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"16":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"f":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"h":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"y":{"1":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.7320508075688772}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.0}}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":7,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":3.605551275463989},"18":{"tf":1.7320508075688772},"20":{"tf":1.7320508075688772},"9":{"tf":1.0}},"e":{".":{"a":{"d":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"(":{"\"":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"k":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":2.0},"19":{"tf":2.0},"20":{"tf":1.0}}}},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"y":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"p":{"df":1,"docs":{"17":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":2.0}}},"df":0,"docs":{}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":3.0},"12":{"tf":2.449489742783178},"13":{"tf":3.3166247903554},"16":{"tf":2.449489742783178},"17":{"tf":4.242640687119285},"19":{"tf":2.23606797749979},"20":{"tf":1.7320508075688772},"8":{"tf":2.23606797749979}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"4":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"o":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":17,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"10":{"tf":4.123105625617661},"11":{"tf":1.0},"12":{"tf":2.23606797749979},"13":{"tf":3.7416573867739413},"14":{"tf":2.449489742783178},"16":{"tf":2.23606797749979},"17":{"tf":3.1622776601683795},"18":{"tf":2.8284271247461903},"19":{"tf":1.4142135623730951},"20":{"tf":2.0},"22":{"tf":1.7320508075688772},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":2.0},"17":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":7,"docs":{"0":{"tf":1.0},"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.0},"21":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":4,"docs":{"10":{"tf":2.0},"18":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"1":{"tf":1.0}}}},"t":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"19":{"tf":1.0}}}}}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.4142135623730951}},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"16":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"19":{"tf":1.0},"9":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"18":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":1,"docs":{"10":{"tf":2.23606797749979}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.0}}}},"n":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}}},"df":2,"docs":{"18":{"tf":1.0},"20":{"tf":1.0}}}}}}},"df":10,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":2.449489742783178},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":2.449489742783178},"19":{"tf":1.7320508075688772},"3":{"tf":2.0},"4":{"tf":1.7320508075688772},"8":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"s":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}}}}},"w":{"df":1,"docs":{"10":{"tf":1.0}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":2.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":2.0},"20":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":8,"docs":{"13":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.23606797749979},"3":{"tf":1.0},"6":{"tf":1.7320508075688772}}},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"14":{"tf":1.0}}}},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"d":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"16":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.23606797749979}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"14":{"tf":1.0},"19":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}},"df":1,"docs":{"15":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"t":{"df":11,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"4":{"tf":2.8284271247461903},"6":{"tf":1.0}},"n":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":2.0},"16":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}},"i":{"df":3,"docs":{"16":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0}}}}},"z":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":6,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":3.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"22":{"tf":1.0}}}},"c":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0}}}}}},"df":0,"docs":{}}},"r":{"c":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"f":{"df":1,"docs":{"3":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":2.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":8,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":2.0}}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"6":{"tf":3.4641016151377544}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":3.0}},"u":{"df":0,"docs":{},"r":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":6,"docs":{"16":{"tf":2.8284271247461903},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.7320508075688772},"8":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"/":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0}}}}}}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":8,"docs":{"10":{"tf":4.69041575982343},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.3166247903554},"18":{"tf":1.7320508075688772},"19":{"tf":3.3166247903554},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951}},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.0}}},"k":{"df":0,"docs":{},"e":{"df":9,"docs":{"1":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"/":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.7320508075688772},"4":{"tf":1.7320508075688772}}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"10":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"l":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"20":{"tf":2.449489742783178}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"{":{"df":0,"docs":{},"r":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"{":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"3":{"tf":1.0}}},"k":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"d":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.0},"14":{"tf":1.4142135623730951},"15":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.8284271247461903},"9":{"tf":1.0}}}}}}}},"i":{"df":1,"docs":{"11":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"1":{".":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"l":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":2,"docs":{"3":{"tf":1.0},"4":{"tf":1.0}}}},"p":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.0}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{"df":1,"docs":{"17":{"tf":3.1622776601683795}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"o":{"df":8,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"7":{"tf":1.0}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"20":{"tf":1.0}},"v":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.7320508075688772},"7":{"tf":2.0},"8":{"tf":2.0}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"8":{";":{"6":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"/":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"k":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}},"p":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":13,"docs":{"0":{"tf":1.7320508075688772},"10":{"tf":2.23606797749979},"12":{"tf":1.4142135623730951},"13":{"tf":3.1622776601683795},"14":{"tf":3.872983346207417},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"v":{"0":{".":{"1":{".":{"0":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":7,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":2.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":1,"docs":{"6":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":1,"docs":{"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"16":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}}}}},"i":{"a":{"df":1,"docs":{"16":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}}}},"d":{"df":4,"docs":{"16":{"tf":2.0},"17":{"tf":4.242640687119285},"19":{"tf":1.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"df":0,"docs":{}}}}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"17":{"tf":3.605551275463989}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"16":{"tf":2.6457513110645907},"17":{"tf":5.196152422706632},"18":{"tf":1.4142135623730951},"19":{"tf":2.23606797749979},"20":{"tf":2.449489742783178}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}},"y":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":2.0},"19":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":10,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}},"l":{"d":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":10,"docs":{"1":{"tf":1.4142135623730951},"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.449489742783178},"5":{"tf":2.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":6,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"4":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"x":{"4":{"c":{"df":8,"docs":{"0":{"tf":2.23606797749979},"1":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":4.0},"15":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"4":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"19":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"1":{"tf":1.0},"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"title":{"root":{"b":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0}}}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"17":{"tf":1.0},"7":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"x":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"df":0,"docs":{}}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"h":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}}}}},"p":{"4":{"df":1,"docs":{"17":{"tf":1.0}}},"a":{"c":{"df":0,"docs":{},"k":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"11":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":1,"docs":{"13":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"3":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"16":{"tf":1.0}}}},"df":0,"docs":{}}}}},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}},"df":0,"docs":{}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"5":{"tf":1.0}}},"df":0,"docs":{}}}}},"x":{"4":{"c":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"lang":"English","pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5"},"results_options":{"limit_results":30,"teaser_word_count":30},"search_options":{"bool":"OR","expand":true,"fields":{"body":{"boost":1},"breadcrumbs":{"boost":1},"title":{"boost":2}}}}); \ No newline at end of file diff --git a/book/searchindex.json b/book/searchindex.json new file mode 100644 index 00000000..8aed08cb --- /dev/null +++ b/book/searchindex.json @@ -0,0 +1 @@ +{"doc_urls":["intro.html#the-x4c-book","01-basics.html#the-basics","01-01-installation.html#installation","01-01-installation.html#rust","01-01-installation.html#x4c","01-02-hello_world.html#hello-world","01-02-hello_world.html#parsing","01-02-hello_world.html#data-types","01-02-hello_world.html#structs","01-02-hello_world.html#headers","01-02-hello_world.html#control-blocks","01-02-hello_world.html#package","01-02-hello_world.html#full-program","01-03-compile_and_run.html#compile-and-run","01-03-compile_and_run.html#softnpu-and-target-x4c-use-cases","02-by-example.html#by-example","02-01-vlan-switch.html#vlan-switch","02-01-vlan-switch.html#p4-data-plane-program","02-01-vlan-switch.html#rust-control-plane-program","02-01-vlan-switch.html#control-plane-code","02-01-vlan-switch.html#test-code","03-guidelines.html#guidelines","03-01-endianness.html#endianness"],"index":{"documentStore":{"docInfo":{"0":{"body":43,"breadcrumbs":4,"title":2},"1":{"body":33,"breadcrumbs":2,"title":1},"10":{"body":519,"breadcrumbs":5,"title":2},"11":{"body":45,"breadcrumbs":4,"title":1},"12":{"body":141,"breadcrumbs":5,"title":2},"13":{"body":374,"breadcrumbs":5,"title":2},"14":{"body":238,"breadcrumbs":8,"title":5},"15":{"body":14,"breadcrumbs":2,"title":1},"16":{"body":98,"breadcrumbs":5,"title":2},"17":{"body":722,"breadcrumbs":7,"title":4},"18":{"body":145,"breadcrumbs":7,"title":4},"19":{"body":271,"breadcrumbs":6,"title":3},"2":{"body":0,"breadcrumbs":3,"title":1},"20":{"body":274,"breadcrumbs":5,"title":2},"21":{"body":8,"breadcrumbs":2,"title":1},"22":{"body":66,"breadcrumbs":3,"title":1},"3":{"body":34,"breadcrumbs":3,"title":1},"4":{"body":99,"breadcrumbs":3,"title":1},"5":{"body":9,"breadcrumbs":5,"title":2},"6":{"body":195,"breadcrumbs":4,"title":1},"7":{"body":8,"breadcrumbs":5,"title":2},"8":{"body":115,"breadcrumbs":4,"title":1},"9":{"body":115,"breadcrumbs":4,"title":1}},"docs":{"0":{"body":"This book provides an introduction to the P4 language using the x4c compiler. The presentation is by example. Each concept is introduced through example P4 code and programs - then demonstrated using simple harnesses that pass packets through compiled P4 pipelines. A basic knowledge of programming and networking is assumed. The x4c Rust compilation target will be used in this book, so a working knowledge of Rust is also good to have.","breadcrumbs":"The x4c Book » The x4c Book","id":"0","title":"The x4c Book"},"1":{"body":"This chapter will take you from zero to a simple hello-world program in P4. This will include. Getting a Rust toolchain setup and installing the x4c compiler. Compiling a P4 hello world program into a Rust program. Writing a bit of Rust code to push packets through the our compiled P4 pipelines.","breadcrumbs":"The Basics » The Basics","id":"1","title":"The Basics"},"10":{"body":"Control blocks are where logic goes that decides what will happen to packets that are parsed successfully. Similar to a parser block, control blocks look a lot like functions from general purpose programming languages. The signature (the number and type of arguments) for this control block is a bit different than the parser block above. The first argument hdr, is the output of the parser block. Note in the parser signature there is a out headers_t headers parameter, and in this control block there is a inout headers_t hdr parameter. The out direction in the parser means that the parser writes to this parameter. The inout direction in the control block means that the control both reads and writes to this parameter. The ingress_metadata_t parameter is the same parameter we saw in the parser block. The egress_metadata_t is similar to ingress_metadata_t. However, our code uses this parameter to inform the ASIC about how it should treat packets on egress. This is in contrast to the ingress_metdata_t parameter that is used by the ASIC to inform our program about details of the packet's ingress. control ingress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { action drop() { } action forward(bit<16> port) { egress.port = port; } table tbl { key = { ingress.port: exact; } actions = { drop; forward; } default_action = drop; const entries = { 16w0 : forward(16w1); 16w1 : forward(16w0); } } apply { tbl.apply(); } } Control blocks are made up of tables, actions and apply blocks. When packet headers enter a control block, the apply block decides what tables to run the parameter data through. Tables are described in terms if keys and actions. A key is an ordered sequence of fields that can be extracted from any of the control parameters. In the example above we are using the port field from the ingress parameter to decide what to do with a packet. We are not even investigating the packet headers at all! We can indeed use header fields in keys, and an example of doing so will come later. When a table is applied, and there is an entry in the table that matches the key data, the action corresponding to that key is executed. In our example we have pre-populated our table with two entries. The first entry says, if the ingress port is 0, forward the packet to port 1. The second entry says if the ingress port is 1, forward the packet to port 0. These odd looking prefixes on our numbers are width specifiers. So 16w0 reads: the value 0 with a width of 16 bits. Every action that is specified in a table entry must be defined within the control. In our example, the forward action is defined above. All this action does is set the port field on the egress metadata to the provided value. The example table also has a default action of drop. This action fires for all invocations of the table over key data that has no matching entry. So for our program, any packet coming from a port that is not 0 or 1 will be dropped. The apply block is home to generic procedural code. In our example it's very simple and only has an apply invocation for our table. However, arbitrary logic can go in this block, we could even implement the logic of this control without a table! apply { if (ingress.port == 16w0) { egress.port = 16w1; } if (ingress.port == 16w1) { egress.port = 16w0; }\n} Which then begs the question, why have a special table construct at all. Why not just program everything using logical primitives? Or let programmers define their own data structures like general purpose programming languages do? Setting the performance arguments aside for the moment, there is something mechanically special about tables. They can be updated from outside the P4 program. In the program above we have what are called constant entries defined directly in the P4 program. This makes presenting a simple program like this very straight forward, but it is not the way tables are typically populated. The focus of P4 is on data plane programming e.g., given a packet from the wire what do we do with it? I prime example of this is packet routing and forwarding. Both routing and forwarding are typically implemented in terms of lookup tables. Routing is commonly implemented by longest prefix matching on the destination address of an IP packet and forwarding is commonly implemented by exact table lookups on layer-2 MAC addresses. How are those lookup tables populated though. There are various different answers there. Some common ones include routing protocols like OSPF, or BGP. Address resolution protocols like ARP and NDP. Or even more simple answers like an administrator statically adding a route to the system. All of these activities involve either a stateful protocol of some sort or direct interaction with a user. Neither of those things is possible in the P4 programming language. It's just about processing packets on the wire and the mechanisms for keeping state between packets is extremely limited. What P4 implementations do provide is a way for programs written in general purpose programming languages that are capable of stateful protocol implementation and user interaction - to modify the tables of a running P4 program through a runtime API. We'll come back to runtime APIs soon. For now the point is that the table abstraction allows P4 programs to remain focused on simple, mostly-stateless packet processing tasks that can be implemented at high packet rates and leave the problem of table management to the general purpose programming languages that interact with P4 programs through shared table manipulation.","breadcrumbs":"The Basics » Hello World » Control Blocks","id":"10","title":"Control Blocks"},"11":{"body":"The final bit to show for our hello world program is a package instantiation. A package is like a constructor function that takes a parser and a set of control blocks. Packages are typically tied to the ASIC your P4 code will be executing on. In the example below, we are passing our parser and single control block to the SoftNPU package. Packages for more complex ASICs may take many control blocks as arguments. SoftNPU( parse(), ingress()\n) main;","breadcrumbs":"The Basics » Hello World » Package","id":"11","title":"Package"},"12":{"body":"Putting it all together, we have a complete P4 hello world program as follows. struct headers_t { ethernet_h ethernet;\n} struct ingress_metadata_t { bit<16> port; bool drop;\n} struct egress_metadata_t { bit<16> port; bool drop; bool broadcast;\n} header ethernet_h { bit<48> dst; bit<48> src; bit<16> ether_type;\n} parser parse ( packet_in pkt, out headers_t headers, inout ingress_metadata_t ingress,\n){ state start { pkt.extract(headers.ethernet); transition finish; } state finish { transition accept; }\n} control ingress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { action drop() { } action forward(bit<16> port) { egress.port = port; } table tbl { key = { ingress.port: exact; } actions = { drop; forward; } default_action = drop; const entries = { 16w0 : forward(16w1); 16w1 : forward(16w0); } } apply { tbl.apply(); } } // We do not use an egress controller in this example, but one is required for\n// SoftNPU so just use an empty controller here.\ncontrol egress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { } SoftNPU( parse(), ingress(), egress(),\n) main; This program will take any packet that has an Ethernet header showing up on port 0, send it out port 1, and vice versa. All other packets will be dropped. In the next section we'll compile this program and run some packets through it!","breadcrumbs":"The Basics » Hello World » Full Program","id":"12","title":"Full Program"},"13":{"body":"In the previous section we put together a hello world P4 program. In this section we run that program over a software ASIC called SoftNpu. One of the capabilities of the x4c compiler is using P4 code directly from Rust code and we'll be doing that in this example. Below is a Rust program that imports the P4 code developed in the last section, loads it onto a SoftNpu ASIC instance, and sends some packets through it. We'll be looking at this program piece-by-piece in the remainder of this section. All of the programs in this book are available as buildable programs in the oxidecomputer/p4 repository in the book/code directory. use tests::softnpu::{RxFrame, SoftNpu, TxFrame};\nuse tests::{expect_frames}; p4_macro::use_p4!(p4 = \"book/code/src/bin/hello-world.p4\", pipeline_name = \"hello\"); fn main() -> Result<(), anyhow::Error> { let pipeline = main_pipeline::new(2); let mut npu = SoftNpu::new(2, pipeline, false); let phy1 = npu.phy(0); let phy2 = npu.phy(1); npu.run(); phy1.send(&[TxFrame::new(phy2.mac, 0, b\"hello\")])?; expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b\"hello\")]); phy2.send(&[TxFrame::new(phy1.mac, 0, b\"world\")])?; expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b\"world\")]); Ok(())\n} The program starts with a few Rust imports. use tests::softnpu::{RxFrame, SoftNpu, TxFrame};\nuse tests::{expect_frames}; This first line is the SoftNpu implementation that lives in the test crate of the oxidecomputer/p4 repository. The second is a helper macro that allows us to make assertions about frames coming from a SoftNpu \"physical\" port (referred to as a phy). The next line is using the x4c compiler to translate P4 code into Rust code and dumping that Rust code into our program. The macro literally expands into the Rust code emitted by the compiler for the specified P4 source file. p4_macro::use_p4!(p4 = \"book/code/src/bin/hello-world.p4\", pipeline_name = \"hello\"); The main artifact this produces is a Rust struct called main_pipeline which is used in the code that comes next. let pipeline = main_pipeline::new(2);\nlet mut npu = SoftNpu::new(2, pipeline, false);\nlet phy1 = npu.phy(0);\nlet phy2 = npu.phy(1); This code is instantiating a pipeline object that encapsulates the logic of our P4 program. Then a SoftNpu ASIC is constructed with two ports and our pipeline program. SoftNpu objects provide a phy method that takes a port index to get a reference to a port that is attached to the ASIC. These port objects are used to send and receive packets through the ASIC, which uses our compiled P4 code to process those packets. Next we run our program on the SoftNpu ASIC. npu.run(); However, this does not actually do anything until we pass some packets through it, so lets do that. phy1.send(&[TxFrame::new(phy2.mac, 0, b\"hello\")])?; This code transmits an Ethernet frame through the first port of the ASIC with a payload value of \"hello\". The phy2.mac parameter of the TxFrame sets the destination MAC address and the 0 for the second parameter is the ethertype used in the outgoing Ethernet frame. Based on the logic in our P4 program, we would expect this packet to come out the second port. Let's test that. expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b\"hello\")]); This code reads a packet from the second ASIC port phy2 (blocking until there is a packet available) and asserts the following. The Ethernet payload is the byte string \"hello\". The source MAC address is that of phy1. The ethertype is 0. To complete the hello world program, we do the same thing in the opposite direction. Sending the byte string \"world\" as an Ethernet payload into port 2 and assert that it comes out port 1. phy2.send(&[TxFrame::new(phy1.mac, 0, b\"world\")])?;\nexpect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b\"world\")]); The expect_frames macro will also print payloads and the port they came from. When we run this program we see the following. $ cargo run --bin hello-world Compiling x4c-book v0.1.0 (/home/ry/src/p4/book/code) Finished dev [unoptimized + debuginfo] target(s) in 2.05s Running `target/debug/hello-world`\n[phy2] hello\n[phy1] world","breadcrumbs":"The Basics » Compile and Run » Compile and Run","id":"13","title":"Compile and Run"},"14":{"body":"The example above shows using x4c compiled code is a setting that is only really useful for testing the logic of compiled pipelines and demonstrating how P4 and x4c compiled pipelines work. This begs the question of what the target use cases for x4c actually are. It also raises question, why build x4c in the first place? Why not use the established reference compiler p4c and its associated reference behavioral model bmv2? A key difference between x4c and the p4c ecosystem is how compilation and execution concerns are separated. x4c generates free-standing pipelines that can be used by other code, p4c generates JSON that is interpreted and run by bmv2 . The example above shows how the generation of free-standing runnable pipelines can be used to test the logic of P4 programs in a lightweight way. We went from P4 program source to actual packet processing using nothing but the Rust compiler and package manager. The program is executable in an operating system independent way and is a great way to get CI going for P4 programs. The free-standing pipeline approach is not limited to self-contained use cases with packets that are generated and consumed in-program. x4c generated code conforms to a well defined Pipeline interface that can be used to run pipelines anywhere rustc compiled code can run. Pipelines are even dynamically loadable through dlopen and the like. The x4c authors have used x4c generated pipelines to create virtual ASICs inside hypervisors that transit real traffic between virtual machines, as well as P4 programs running inside zones/containers that implement NAT and tunnel encap/decap capabilities. The mechanics of I/O are deliberately outside the scope of x4c generated code. Whether you want to use DLPI, XDP, libpcap, PF_RING, DPDK, etc., is up to you and the harness code you write around your pipelines! The win with x4c is flexibility. You can compile a free-standing P4 pipeline and use that pipeline wherever you see fit. The near-term use for x4c focuses on development and evaluation environments. If you are building a system around P4 programmable components, but it's not realistic to buy all the switches/routers/ASICs at the scale you need for testing/development, x4c is an option. x4c is also a good option for running packets through your pipelines in a lightweight way in CI.","breadcrumbs":"The Basics » Compile and Run » SoftNpu and Target x4c Use Cases.","id":"14","title":"SoftNpu and Target x4c Use Cases."},"15":{"body":"This chapter presents the use of the P4 language and x4c through a series of examples. This is a living set that will grow over time.","breadcrumbs":"By Example » By Example","id":"15","title":"By Example"},"16":{"body":"This example presents a simple VLAN switch program. This program allows a single VLAN id (vid) to be set per port. Any packet arriving at a port with a vid set must carry that vid in its Ethernet header or it will be dropped. We'll refer to this as VLAN filtering. If a packet makes it past ingress filtering, then the forwarding table of the switch is consulted to see what port to send the packet out. We limit ourselves to a very simple switch here with a static forwarding table. A MAC learning switch will be presented in a later example. This switch also does not do flooding for unknown packets, it simply operates on the lookup table it has. If an egress port is identified via a forwarding table lookup, then egress VLAN filtering is applied. If the vid on the packet is present on the egress port then the packet is forwarded out that port. This example is comprised of two programs. A P4 data-plane program and a Rust control-plane program.","breadcrumbs":"By Example » VLAN Switch » VLAN Switch","id":"16","title":"VLAN Switch"},"17":{"body":"Let's start by taking a look at the headers for the P4 program. header ethernet_h { bit<48> dst; bit<48> src; bit<16> ether_type;\n} header vlan_h { bit<3> pcp; bit<1> dei; bit<12> vid; bit<16> ether_type;\n} struct headers_t { ethernet_h eth; vlan_h vlan;\n} An Ethernet frame is normally just 14 bytes with a 6 byte source and destination plus a two byte ethertype. However, when VLAN tags are present the ethertype is set to 0x8100 and a VLAN header follows. This header contains a 12-bit vid as well as an ethertype for the header that follows. A byte-oriented packet diagram shows how these two Ethernet frame variants line up. 1 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8\n+---------------------------+\n| src | dst |et |\n+---------------------------+\n+-----------------------------------+\n| src | dst |et |pdv|et |\n+------------------------------------ The structure is always the same for the first 14 bytes. So we can take advantage of that when parsing any type of Ethernet frame. Then we can use the ethertype field to determine if we are looking at a regular Ethernet frame or a VLAN-tagged Ethernet frame. parser parse ( packet_in pkt, out headers_t h, inout ingress_metadata_t ingress,\n) { state start { pkt.extract(h.eth); if (h.eth.ether_type == 16w0x8100) { transition vlan; } transition accept; } state vlan { pkt.extract(h.vlan); transition accept; }\n} This parser does exactly what we described above. First parse the first 14 bytes of the packet as an Ethernet frame. Then conditionally parse the VLAN portion of the Ethernet frame if the ethertype indicates we should do so. In a sense we can think of the VLAN portion of the Ethernet frame as being it's own independent header. We are keying our decisions based on the ethertype, just as we would for layer 3 protocol headers. Our VLAN switch P4 program is broken up into multiple control blocks. We'll start with the top level control block and then dive into the control blocks it calls into to implement the switch. control ingress( inout headers_t hdr, inout ingress_metadata_t ingress, inout egress_metadata_t egress,\n) { vlan() vlan; forward() fwd; apply { bit<12> vid = 12w0; if (hdr.vlan.isValid()) { vid = hdr.vlan.vid; } // check vlan on ingress bool vlan_ok = false; vlan.apply(ingress.port, vid, vlan_ok); if (vlan_ok == false) { egress.drop = true; return; } // apply switch forwarding logic fwd.apply(hdr, egress); // check vlan on egress vlan.apply(egress.port, vid, vlan_ok); if (vlan_ok == false) { egress.drop = true; return; } }\n} The first thing that is happening in this program is the instantiation of a few other control blocks. vlan() vlan;\nforward() fwd; We'll be using these control blocks to implement the VLAN filtering and switch forwarding logic. For now let's take a look at the higher level packet processing logic of the program in the apply block. The first thing we do is start by assuming there is no vid by setting it to zero. The if the VLAN header is valid we assign the vid from the packet header to our local vid variable. The isValid header method returns true if extract was called on that header. Recall from the parser code above, that extract is only called on hdr.vlan if the ethertype on the Ethernet frame is 0x1800. bit<12> vid = 12w0;\nif (hdr.vlan.isValid()) { vid = hdr.vlan.vid;\n} Next apply VLAN filtering logic. First an indicator variable vlan_ok is initialized to false. Then we pass that indicator variable along with the port the packet came in on and the vid we determined above to the VLAN control block. bool vlan_ok = false;\nvlan.apply(ingress.port, vid, vlan_ok);\nif (vlan_ok == false) { egress.drop = true; return;\n} Let's take a look at the VLAN control block. The first thing to note here is the direction of parameters. The port and vid parameters are in parameters, meaning that the control block can only read from them. The match parameter is an out parameter meaning the control block can only write to it. Consider this in the context of the code above. There we are passing in the vlan_ok to the control block with the expectation that the control block will modify the value of the variable. The out direction of this control block parameter is what makes that possible. control vlan( in bit<16> port, in bit<12> vid, out bool match,\n) { action no_vid_for_port() { match = true; } action filter(bit<12> port_vid) { if (port_vid == vid) { match = true; } } table port_vlan { key = { port: exact; } actions = { no_vid_for_port; filter; } default_action = no_vid_for_port; } apply { port_vlan.apply(); }\n} Let's look at this control block starting from the table declaration. The port_vlan table has the port id as the single key element. There are two possible actions no_vid_for_port and filter. The no_vid_for_port fires when there is no match for the port id. That action unconditionally sets match to true. The logic here is that if there is no VLAN configure for a port e.g., the port is not in the table, then there is no need to do any VLAN filtering and just pass the packet along. The filter action takes a single parameter port_vid. This value is populated by the table value entry corresponding to the port key. There are no static table entries in this P4 program, they are provided by a control plane program which we'll get to in a bit. The filter logic tests if the port_vid that has been configured by the control plane matches the vid on the packet. If the test passes then match is set to true meaning the packet can continue processing. Popping back up to the top level control block. If vlan_ok was not set to true in the vlan control block, then we drop the packet. Otherwise we continue on to further processing - forwarding. Here we are passing the entire header and egress metadata structures into the fwd control block which is an instantiation of the forward control block type. fwd.apply(hdr, egress); Lets take a look at the forward control block. control forward( inout headers_t hdr, inout egress_metadata_t egress,\n) { action drop() {} action forward(bit<16> port) { egress.port = port; } table fib { key = { hdr.eth.dst: exact; } actions = { drop; forward; } default_action = drop; } apply { fib.apply(); }\n} This simple control block contains a table that maps Ethernet addresses to ports. The single element key contains an Ethernet destination and the matching action forward contains a single 16-bit port value. When the Ethernet destination matches an entry in the table, the egress metadata destination for the packet is set to the port id that has been set for that table entry. Note that in this control block both parameters have an inout direction, meaning the control block can both read from and write to these parameters. Like the vlan control block above, there are no static entries here. Entries for the table in this control block are filled in by a control-plane program. Popping back up the stack to our top level control block, the remaining code we have is the following. vlan.apply(egress.port, vid, vlan_ok);\nif (vlan_ok == false) { egress.drop = true; return;\n} This is pretty much the same as what we did at the beginning of the apply block. Except this time, we are passing in the egress port instead of the ingress port. We are checking the VLAN tags not only for the ingress port, but also for the egress port. You can find this program in it's entirety here .","breadcrumbs":"By Example » VLAN Switch » P4 Data-Plane Program","id":"17","title":"P4 Data-Plane Program"},"18":{"body":"The main purpose of the Rust control plane program is to manage table entries in the P4 program. In addition to table management, the program we'll be showing here also instantiates and runs the P4 code over a virtual ASIC to demonstrate the complete system working. We'll start top down again. Here is the beginning of our Rust program. use tests::expect_frames;\nuse tests::softnpu::{RxFrame, SoftNpu, TxFrame}; p4_macro::use_p4!( p4 = \"book/code/src/bin/vlan-switch.p4\", pipeline_name = \"vlan_switch\"\n); fn main() -> Result<(), anyhow::Error> { let mut pipeline = main_pipeline::new(2); let m1 = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33]; let m2 = [0x44, 0x44, 0x44, 0x44, 0x44, 0x44]; init_tables(&mut pipeline, m1, m2); run_test(pipeline, m2)\n} After imports, the first thing we are doing is calling the use_p4! macro. This translates our P4 program into Rust and expands the use_p4! macro in place to the generated Rust code. This results in the main_pipeline type that we see instantiated in the first line of the main program. Then we define a few MAC addresses that we'll get back to later. The remainder of the main code performs the two functions described above. The init_tables function acts as a control plane for our P4 code, setting up the VLAN and forwarding tables. The run_test code executes our instantiated pipeline over a virtual ASIC, sends some packets through it, and makes assertions about the results.","breadcrumbs":"By Example » VLAN Switch » Rust Control-Plane Program","id":"18","title":"Rust Control-Plane Program"},"19":{"body":"Let's jump into the control plane code. fn init_tables(pipeline: &mut main_pipeline, m1: [u8;6], m2: [u8;6]) { // add static forwarding entries pipeline.add_ingress_fwd_fib_entry(\"forward\", &m1, &0u16.to_be_bytes()); pipeline.add_ingress_fwd_fib_entry(\"forward\", &m2, &1u16.to_be_bytes()); // port 0 vlan 47 pipeline.add_ingress_vlan_port_vlan_entry( \"filter\", 0u16.to_be_bytes().as_ref(), 47u16.to_be_bytes().as_ref(), ); // sanity check the table let x = pipeline.get_ingress_vlan_port_vlan_entries(); println!(\"{:#?}\", x); // port 1 vlan 47 pipeline.add_ingress_vlan_port_vlan_entry( \"filter\", 1u16.to_be_bytes().as_ref(), 47u16.to_be_bytes().as_ref(), ); } The first thing that happens here is the forwarding tables are set up. We add two entries one for each MAC address. The first MAC address maps to the first port and the second MAC address maps to the second port. We are using table modification methods from the Rust code that was generated from our P4 code. A valid question is, how do I know what these are? There are two ways. Determine Based on P4 Code Structure The naming is deterministic based on the structure of the p4 program. Table modification functions follow the pattern ___entry. Where operation one of the following. add remove get. The control_path is based on the names of control instances starting from the top level ingress controller. In our P4 program, the forwarding table is named fwd so that is what we see in the function above. If there is a longer chain of controller instances, the instance names are underscore separated. Finally the table_name is the name of the table in the control block. This is how we arrive at the method name above. pipeline.add_fwd_fib_entry(...) Use cargo doc Alternatively you can just run cargo doc to have Cargo generate documentation for your crate that contains the P4-generated Rust code. This will emit Rust documentation that includes documentation for the generated code. Now back to the control plane code above. You'll also notice that we are adding key values and parameter values to the P4 tables as byte slices. At the time of writing, x4c is not generating high-level table manipulation APIs so we have to pass everything in as binary serialized data. The semantics of these data buffers are the following. Both key data and match action data (parameters) are passed in in-order. Numeric types are serialized in big-endian byte order. If a set of keys or a set of parameters results in a size that does not land on a byte-boundary, i.e. 12 bytes like we have in this example, the length of the buffer is rounded up to the nearest byte boundary. After adding the forwarding entries, VLAN table entries are added in the same manner. A VLAN with the vid of 47 is added to the first and second ports. Note that we also use a table access method to get all the entries of a table and print them out to convince ourselves our code is doing what we intend.","breadcrumbs":"By Example » VLAN Switch » Control Plane Code","id":"19","title":"Control Plane Code"},"2":{"body":"","breadcrumbs":"The Basics » Installation » Installation","id":"2","title":"Installation"},"20":{"body":"Now let's take a look at the test portion of our code. fn run_test( pipeline: main_pipeline, m2: [u8; 6], m3: [u8; 6],\n) -> Result<(), anyhow::Error> { // create and run the softnpu instance let mut npu = SoftNpu::new(2, pipeline, false); let phy1 = npu.phy(0); let phy2 = npu.phy(1); npu.run(); // send a packet we expect to make it through phy1.send(&[TxFrame::newv(m2, 0, b\"blueberry\", 47)])?; expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b\"blueberry\", 47)]); // send 3 packets, we expect the first 2 to get filtered by vlan rules phy1.send(&[TxFrame::newv(m2, 0, b\"poppyseed\", 74)])?; // 74 != 47 phy1.send(&[TxFrame::new(m2, 0, b\"banana\")])?; // no tag phy1.send(&[TxFrame::newv(m2, 0, b\"muffin\", 47)])?; phy1.send(&[TxFrame::newv(m3, 0, b\"nut\", 47)])?; // no forwarding entry expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b\"muffin\", 47)]); Ok(())\n} The first thing we do here is create a SoftNpu virtual ASIC instance with 2 ports that will execute the pipeline we configured with entries in the previous section. We get references to each ASIC port and run the ASIC. Next we send a few packets through the ASIC to validate that our P4 program is doing what we expect given how we have configured the tables. The first test passes through a packet we expect to make it through the VLAN filtering. The next test sends 4 packets in the ASIC, but we expect our P4 program to filter 3 of them out. The first packet has the wrong vid. The second packet has no vid. The third packet should make it through. The fourth packet has no forwarding entry. Running the test When we run this program we see the following $ cargo run --bin vlan-switch Finished dev [unoptimized + debuginfo] target(s) in 0.11s Running `target/debug/vlan-switch`\n[ TableEntry { action_id: \"filter\", keyset_data: [ 0, 0, ], parameter_data: [ 0, 47, ], },\n]\n[phy2] blueberry\ndrop\ndrop\ndrop\n[phy2] muffin The first thing we see is our little sanity check dumping out the VLAN table after adding a single entry. This has what we expect, mapping the port 0 to the vid 47. Next we start sending packets through the ASIC. There are two frame constructors in play here. TxFrame::newv creates an Ethernet frame with a VLAN header and TxFrame::new creates just a plane old Ethernet frame. The first argument to each frame constructor is the destination MAC address. The second argument is the ethertype to use and the third argument is the Ethernet payload. Next we see that our blueberry packet made it through as expected. Then we see three packets getting dropped as we expect. And finally we see the muffin packet coming through as expected. You can find this program in it's entirety here .","breadcrumbs":"By Example » VLAN Switch » Test Code","id":"20","title":"Test Code"},"21":{"body":"Ths chapter provides guidelines on various aspects of the x4c compiler.","breadcrumbs":"Guidelines » Guidelines","id":"21","title":"Guidelines"},"22":{"body":"The basic rules for endianness follow. Generally speaking numeric fields are in big endian when they come in off the wire, little endian while in the program, and transformed back to big endian on the way back out onto the wire. We refer to this as confused endian. All numeric packet field data is big endian when enters and leaves a p4 program. All numeric data, including packet fields is little endian inside a p4 program. Table keys with the exact and range type defined over bit types are in little endian. Table keys with the lpm type are in the byte order they appear on the wire.","breadcrumbs":"Guidelines » Endianness » Endianness","id":"22","title":"Endianness"},"3":{"body":"The first thing we'll need to do is install Rust. We'll be using a tool called rustup . On Unix/Linux like platforms, simply run the following from your terminal. For other platforms see the rustup docs. curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh It may be necessary to restart your shell session after installing Rust.","breadcrumbs":"The Basics » Installation » Rust","id":"3","title":"Rust"},"4":{"body":"Now we will install the x4c compiler using the rust cargo tool. cargo install --git https://github.com/oxidecomputer/p4 x4c You should now be able to run x4c. x4c --help\nx4c 0.1 USAGE: x4c [OPTIONS] [TARGET] ARGS: File to compile What target to generate code for [default: rust] [possible values: rust, red-hawk, docs] OPTIONS: --check Just check code, do not compile -h, --help Print help information -o, --out Filename to write generated code to [default: out.rs] --show-ast Show parsed abstract syntax tree --show-hlir Show high-level intermediate representation info --show-pre Show parsed preprocessor info --show-tokens Show parsed lexical tokens -V, --version Print version information That's it! We're now ready to dive into P4 code.","breadcrumbs":"The Basics » Installation » x4c","id":"4","title":"x4c"},"5":{"body":"Let's start out our introduction of P4 with the obligatory hello world program.","breadcrumbs":"The Basics » Hello World » Hello World","id":"5","title":"Hello World"},"6":{"body":"The first bit of programmable logic packets hit in a P4 program is a parser. Parsers do the following. Describe a state machine packet parsing. Extract raw data into headers with typed fields. Decide if a packet should be accepted or rejected based on parsed structure. In the code below, we can see that parsers are defined somewhat like functions in general-purpose programming languages. They take a set of parameters and have a curly-brace delimited block of code that acts over those parameters. Each of the parameters has an optional direction that we see here as out or inout, a type, and a name. We'll get to data types in the next section for now let's focus on what this parser code is doing. The parameters shown here are typical of what you will see for P4 parsers. The exact set of parameters varies depending on ASIC the P4 code is being compiled for. But in general, there will always need to be - a packet, set of headers to extract packet data into and a bit of metadata about the packet that the ASIC has collected. parser parse ( packet_in pkt, out headers_t headers, inout ingress_metadata_t ingress,\n){ state start { pkt.extract(headers.ethernet); transition finish; } state finish { transition accept; }\n} Parsers are made up of a set of states and transitions between those states. Parsers must always include a start state . Our start state extracts an Ethernet header from the incoming packet and places it in to the headers_t parameter passed to the parser. We then transition to the finish state where we simply transition to the implicit accept state. We could have just transitioned to accept from start, but wanted to show transitions between user-defined states in this example. Transitioning to the accept state means that the packet will be passed to a control block for further processing. Control blocks will be covered a few sections from now. Parsers can also transition to the implicit reject state. This means that the packet will be dropped and not go on to any further processing.","breadcrumbs":"The Basics » Hello World » Parsing","id":"6","title":"Parsing"},"7":{"body":"There are two primary data types in P4, struct and header types.","breadcrumbs":"The Basics » Hello World » Data Types","id":"7","title":"Data Types"},"8":{"body":"Structs in P4 are similar to structs you'll find in general purpose programming languages such as C, Rust, and Go. They are containers for data with typed data fields. They can contain basic data types, headers as well as other structs. Let's take a look at the structs in use by our hello world program. The first is a structure containing headers for our program to extract packet data into. This headers_t structure is simple and only contains one header. However, there may be an arbitrary number of headers in the struct. We'll discuss headers in the next section. struct headers_t { ethernet_t ethernet;\n} The next structure is a bit of metadata provided to our parser by the ASIC. In our simple example this just includes the port that the packet came from. So if our code is running on a four port switch, the port field would take on a value between 0 and 3 depending on which port the packet came in on. struct ingress_metadata_t { bit<16> port;\n} As the name suggests bit<16> is a 16-bit value. In P4 the bit type commonly represents unsigned integer values. We'll get more into the primitive data types of P4 later.","breadcrumbs":"The Basics » Hello World » Structs","id":"8","title":"Structs"},"9":{"body":"Headers are the result of parsing packets. They are similar in nature to structures with the following differences. Headers may not contain headers. Headers have a set of methods isValid(), setValid(), and setValid() that provide a means for parsers and control blocks to coordinate on the parsed structure of packets as they move through pipelines. Let's take a look at the ethernet_h header in our hello world example. header ethernet_h { bit<48> dst; bit<48> src; bit<16> ether_type;\n} This header represents a layer-2 Ethernet frame . The leading octet is not present as this will be removed by most ASICs. What remains is the MAC source and destination fields which are each 6 octets / 48 bits and the ethertype which is 2 octets. Note also that the payload is not included here. This is important. P4 programs typically operate on packet headers and not packet payloads. In upcoming examples we'll go over header stacks that include headers at higher layers like IP, ICMP and TCP. In the parsing code above, when pkt.extract(headers.ethernet) is called, the values dst, src and ether_type are populated from packet data and the method setValid() is implicitly called on the headers.ethernet header.","breadcrumbs":"The Basics » Hello World » Headers","id":"9","title":"Headers"}},"length":23,"save":true},"fields":["title","body","breadcrumbs"],"index":{"body":{"root":{"0":{".":{"1":{"1":{"df":1,"docs":{"20":{"tf":1.0}}},"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":3.1622776601683795},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":3.0},"8":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"x":{"1":{"8":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"4":{"4":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"8":{"1":{"0":{"0":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"2":{"df":2,"docs":{"17":{"tf":1.0},"19":{"tf":1.0}},"w":{"0":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"4":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"6":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.0}},"w":{"0":{"df":2,"docs":{"10":{"tf":2.0},"12":{"tf":1.0}},"x":{"8":{"1":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"19":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"5":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"3":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"4":{"7":{"df":2,"docs":{"19":{"tf":1.7320508075688772},"20":{"tf":2.8284271247461903}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"8":{"df":1,"docs":{"9":{"tf":1.0}}},"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"5":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"6":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"7":{"4":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"8":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"9":{"df":1,"docs":{"17":{"tf":1.0}}},"a":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":6,"docs":{"10":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":4,"docs":{"10":{"tf":3.3166247903554},"12":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"v":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"d":{"df":1,"docs":{"19":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":6,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0}}}}}}},"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.0}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.6457513110645907}}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":1.0},"20":{"tf":1.7320508075688772}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"p":{"df":1,"docs":{"10":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"c":{"df":9,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.4142135623730951},"13":{"tf":2.8284271247461903},"14":{"tf":1.0},"18":{"tf":1.4142135623730951},"20":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}},"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"0":{"tf":1.0},"17":{"tf":1.0}}}}},"t":{"df":1,"docs":{"4":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"b":{"\"":{"b":{"a":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"n":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":2.0}}}}}}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}}},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":5,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"i":{"c":{"df":4,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"22":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.0}},"g":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.0},"18":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"6":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":2.0}}},"6":{"df":4,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.0}}},"3":{"df":1,"docs":{"17":{"tf":1.0}}},"4":{"8":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"17":{"tf":1.7320508075688772},"22":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":7,"docs":{"10":{"tf":4.0},"11":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":5.0990195135927845},"19":{"tf":1.0},"6":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"v":{"2":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951}}},"l":{"df":2,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"a":{"d":{"c":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"y":{"df":1,"docs":{"14":{"tf":1.0}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"19":{"tf":2.23606797749979},"22":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"3":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":4,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.7320508075688772}}}}},"df":1,"docs":{"8":{"tf":1.0}},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"i":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"o":{"d":{"df":0,"docs":{},"e":{"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":3.4641016151377544},"14":{"tf":2.449489742783178},"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"19":{"tf":3.0},"20":{"tf":1.4142135623730951},"4":{"tf":2.0},"6":{"tf":2.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":2.0},"20":{"tf":1.0},"22":{"tf":1.0}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":8,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":2.8284271247461903},"21":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0}}},"x":{"df":1,"docs":{"11":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"11":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":9,"docs":{"10":{"tf":3.605551275463989},"11":{"tf":1.7320508075688772},"12":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":5.477225575051661},"18":{"tf":1.7320508075688772},"19":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"20":{"tf":2.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":9,"docs":{"10":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":2.0},"22":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.4142135623730951},"8":{"tf":2.23606797749979},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":2.0},"14":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}},"i":{"df":1,"docs":{"17":{"tf":1.0}}},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}}},"v":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.0}}}}}}}},"i":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}},"o":{"c":{"df":3,"docs":{"19":{"tf":1.4142135623730951},"3":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}}}}}},"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"p":{"d":{"df":0,"docs":{},"k":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":6,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.449489742783178},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":2.0},"6":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"0":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"6":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":2.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"17":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.7320508075688772},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.23606797749979},"16":{"tf":1.7320508075688772},"17":{"tf":3.0}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"n":{"c":{"a":{"df":0,"docs":{},"p":{"/":{"d":{"df":0,"docs":{},"e":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":3.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"17":{"tf":2.449489742783178},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"20":{"tf":2.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}},"h":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"h":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":3.4641016151377544},"20":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":12,"docs":{"0":{"tf":1.4142135623730951},"10":{"tf":2.6457513110645907},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":1.4142135623730951},"16":{"tf":1.7320508075688772},"19":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0},"20":{"tf":1.0}}}}},"df":0,"docs":{}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"!":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"20":{"tf":3.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":5,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"i":{"b":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"d":{"df":6,"docs":{"10":{"tf":2.0},"17":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"4":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":1,"docs":{"17":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.7320508075688772},"17":{"tf":2.6457513110645907},"19":{"tf":1.4142135623730951},"20":{"tf":2.0}}}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}},"d":{"df":3,"docs":{"17":{"tf":1.0},"20":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.7320508075688772}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":10,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":2.6457513110645907},"18":{"tf":1.4142135623730951},"19":{"tf":2.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"16":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"6":{"tf":1.0}},"s":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":9,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"(":{"1":{"6":{"df":0,"docs":{},"w":{"0":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"1":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"6":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"8":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.7320508075688772},"17":{"tf":3.0},"20":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":2.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.0}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}}}}},"w":{"d":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"h":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":2,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"10":{"tf":2.23606797749979},"14":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"t":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.0},"20":{"tf":1.0}}}}}},"o":{"df":5,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"o":{"d":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"15":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}},"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}}},"r":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"w":{"df":0,"docs":{},"k":{"df":1,"docs":{"4":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"d":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{".":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951}}}},"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":2.0},"12":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":3.605551275463989},"20":{"tf":1.0},"6":{"tf":2.0},"7":{"tf":1.0},"8":{"tf":2.23606797749979},"9":{"tf":3.4641016151377544}},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}},"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":7,"docs":{"1":{"tf":1.4142135623730951},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"5":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"p":{"df":1,"docs":{"4":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":8,"docs":{"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"df":0,"docs":{},"p":{"4":{"/":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.0}},"s":{":":{"/":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"u":{"b":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}}}},"i":{".":{"df":1,"docs":{"19":{"tf":1.0}}},"/":{"df":0,"docs":{},"o":{"df":1,"docs":{"14":{"tf":1.0}}}},"c":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"df":2,"docs":{"16":{"tf":1.0},"17":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.4142135623730951}}}}}}},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"9":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.0},"10":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"14":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}},"x":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"4":{"tf":1.4142135623730951}},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":7,"docs":{"10":{"tf":2.449489742783178},"11":{"tf":1.0},"12":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.0},"6":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.6457513110645907},"17":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"22":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.0},"3":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951}}},"n":{"c":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"8":{"tf":1.0}}},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"a":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"0":{"tf":1.0}},"t":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"c":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"t":{"'":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"y":{"df":6,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"19":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}}},"l":{"a":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":2.23606797749979},"15":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"8":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}},"v":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"t":{"'":{"df":8,"docs":{"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":2,"docs":{"13":{"tf":1.0},"17":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":3,"docs":{"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}}},"i":{"b":{"df":0,"docs":{},"p":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}}}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"l":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"15":{"tf":1.0}}}}},"o":{"a":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":5,"docs":{"10":{"tf":2.0},"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"6":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"k":{"df":6,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"p":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}},"m":{"1":{"df":2,"docs":{"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951}}},"2":{"df":3,"docs":{"18":{"tf":1.7320508075688772},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"a":{"c":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"9":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"18":{"tf":2.0}}}},"k":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"p":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}},"i":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"19":{"tf":2.449489742783178},"6":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":4,"docs":{"14":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}}}}},"x":{"df":0,"docs":{},"t":{"df":6,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"17":{"tf":1.0},"20":{"tf":2.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}},"o":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"9":{"tf":1.0}}},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"(":{"0":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"1":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}},"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}}}}},"d":{"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"4":{"tf":1.0}},"k":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"l":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"n":{"df":5,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"19":{"tf":1.4142135623730951},"8":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"22":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{">":{"_":{"<":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{">":{"_":{"<":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{">":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":4,"docs":{"14":{"tf":1.0},"16":{"tf":1.0},"19":{"tf":1.0},"9":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.4142135623730951},"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"f":{"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}}}},"t":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":11,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"5":{"tf":1.0},"6":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"4":{"_":{"df":0,"docs":{},"m":{"a":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"4":{"!":{"(":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"c":{"df":1,"docs":{"14":{"tf":1.7320508075688772}}},"df":20,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"10":{"tf":2.8284271247461903},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":2.6457513110645907},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":2.23606797749979},"19":{"tf":2.449489742783178},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"4":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}},"a":{"c":{"df":0,"docs":{},"k":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"11":{"tf":2.449489742783178},"14":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"10":{"tf":1.0}}},"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}}},"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":3.872983346207417},"12":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.7320508075688772},"16":{"tf":2.449489742783178},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"20":{"tf":3.605551275463989},"22":{"tf":1.4142135623730951},"6":{"tf":3.0},"8":{"tf":1.7320508075688772},"9":{"tf":2.23606797749979}}}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":3.3166247903554},"13":{"tf":1.4142135623730951},"17":{"tf":3.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.449489742783178}},"e":{"df":0,"docs":{},"r":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"s":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"12":{"tf":1.4142135623730951},"17":{"tf":2.0},"4":{"tf":1.7320508075688772},"6":{"tf":2.0},"9":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":2.6457513110645907},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.1622776601683795},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":7,"docs":{"0":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"6":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":3,"docs":{"13":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}},"d":{"df":0,"docs":{},"v":{"df":0,"docs":{},"|":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"16":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"f":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"h":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"y":{"1":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.7320508075688772}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.0}}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":7,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":3.605551275463989},"18":{"tf":1.7320508075688772},"20":{"tf":1.7320508075688772},"9":{"tf":1.0}},"e":{".":{"a":{"d":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"(":{"\"":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"k":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"18":{"tf":1.7320508075688772},"19":{"tf":1.7320508075688772},"20":{"tf":1.0}}}},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"y":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"p":{"df":1,"docs":{"17":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":2.0}}},"df":0,"docs":{}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":3.0},"12":{"tf":2.449489742783178},"13":{"tf":3.3166247903554},"16":{"tf":2.449489742783178},"17":{"tf":4.242640687119285},"19":{"tf":2.23606797749979},"20":{"tf":1.7320508075688772},"8":{"tf":2.23606797749979}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"4":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"o":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":17,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"10":{"tf":4.123105625617661},"11":{"tf":1.0},"12":{"tf":2.0},"13":{"tf":3.7416573867739413},"14":{"tf":2.449489742783178},"16":{"tf":2.23606797749979},"17":{"tf":3.0},"18":{"tf":2.6457513110645907},"19":{"tf":1.4142135623730951},"20":{"tf":2.0},"22":{"tf":1.7320508075688772},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":2.0},"17":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":7,"docs":{"0":{"tf":1.0},"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.0},"21":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":4,"docs":{"10":{"tf":2.0},"18":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"1":{"tf":1.0}}}},"t":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"19":{"tf":1.0}}}}}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.4142135623730951}},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"16":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"19":{"tf":1.0},"9":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"18":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":1,"docs":{"10":{"tf":2.23606797749979}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.0}}}},"n":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}}},"df":2,"docs":{"18":{"tf":1.0},"20":{"tf":1.0}}}}}}},"df":10,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":2.23606797749979},"19":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"4":{"tf":1.7320508075688772},"8":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"s":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}}}}},"w":{"df":1,"docs":{"10":{"tf":1.0}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":2.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":2.0},"20":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":8,"docs":{"13":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.23606797749979},"3":{"tf":1.0},"6":{"tf":1.7320508075688772}}},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"14":{"tf":1.0}}}},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"d":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"16":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.23606797749979}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"14":{"tf":1.0},"19":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}},"df":1,"docs":{"15":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"t":{"df":11,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"4":{"tf":2.8284271247461903},"6":{"tf":1.0}},"n":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":2.0},"16":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}},"i":{"df":3,"docs":{"16":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0}}}}},"z":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":6,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":3.0},"14":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"22":{"tf":1.0}}}},"c":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0}}}}}},"df":0,"docs":{}}},"r":{"c":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"f":{"df":1,"docs":{"3":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":2.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":8,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":2.0}}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"6":{"tf":3.4641016151377544}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":2.8284271247461903}},"u":{"df":0,"docs":{},"r":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":4,"docs":{"16":{"tf":2.449489742783178},"17":{"tf":2.0},"20":{"tf":1.4142135623730951},"8":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"/":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0}}}}}}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":8,"docs":{"10":{"tf":4.69041575982343},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.3166247903554},"18":{"tf":1.7320508075688772},"19":{"tf":3.3166247903554},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951}},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.0}}},"k":{"df":0,"docs":{},"e":{"df":9,"docs":{"1":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"/":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.4142135623730951},"4":{"tf":1.7320508075688772}}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"10":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"l":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"20":{"tf":2.23606797749979}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"{":{"df":0,"docs":{},"r":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"{":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"3":{"tf":1.0}}},"k":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"d":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.0},"14":{"tf":1.4142135623730951},"15":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.8284271247461903},"9":{"tf":1.0}}}}}}}},"i":{"df":1,"docs":{"11":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"1":{".":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"l":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":2,"docs":{"3":{"tf":1.0},"4":{"tf":1.0}}}},"p":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.0}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{"df":1,"docs":{"17":{"tf":3.1622776601683795}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"o":{"df":8,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"7":{"tf":1.0}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"20":{"tf":1.0}},"v":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"8":{"tf":2.0}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"8":{";":{"6":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"/":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"k":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}},"p":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":13,"docs":{"0":{"tf":1.7320508075688772},"10":{"tf":2.23606797749979},"12":{"tf":1.4142135623730951},"13":{"tf":3.1622776601683795},"14":{"tf":3.7416573867739413},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"v":{"0":{".":{"1":{".":{"0":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":7,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":2.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":1,"docs":{"6":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":1,"docs":{"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"16":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}}}}},"i":{"a":{"df":1,"docs":{"16":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}}}},"d":{"df":4,"docs":{"16":{"tf":2.0},"17":{"tf":4.242640687119285},"19":{"tf":1.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"df":0,"docs":{}}}}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"17":{"tf":3.605551275463989}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"16":{"tf":2.23606797749979},"17":{"tf":5.0990195135927845},"18":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":2.23606797749979}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}},"y":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":2.0},"19":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":10,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}},"l":{"d":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":7,"docs":{"1":{"tf":1.4142135623730951},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.449489742783178},"5":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":6,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"4":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"x":{"4":{"c":{"df":8,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":3.872983346207417},"15":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"4":{"tf":2.6457513110645907}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"19":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"1":{"tf":1.0},"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"breadcrumbs":{"root":{"0":{".":{"1":{"1":{"df":1,"docs":{"20":{"tf":1.0}}},"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.0},"12":{"tf":1.0},"13":{"tf":3.1622776601683795},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":3.0},"8":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"x":{"1":{"8":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"3":{"3":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"4":{"4":{"df":1,"docs":{"18":{"tf":2.449489742783178}}},"df":0,"docs":{}},"8":{"1":{"0":{"0":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"2":{"df":2,"docs":{"17":{"tf":1.0},"19":{"tf":1.0}},"w":{"0":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"4":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"6":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.0}},"w":{"0":{"df":2,"docs":{"10":{"tf":2.0},"12":{"tf":1.0}},"x":{"8":{"1":{"0":{"0":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"1":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"19":{"tf":1.0}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"2":{".":{"0":{"5":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"3":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"8":{"tf":1.0}}},"4":{"7":{"df":2,"docs":{"19":{"tf":1.7320508075688772},"20":{"tf":2.8284271247461903}},"u":{"1":{"6":{".":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"_":{"b":{"df":0,"docs":{},"e":{"_":{"b":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{")":{".":{"a":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"8":{"df":1,"docs":{"9":{"tf":1.0}}},"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"5":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"6":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"7":{"4":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"8":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"9":{"df":1,"docs":{"17":{"tf":1.0}}},"a":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":6,"docs":{"10":{"tf":2.0},"14":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":2.23606797749979}}}},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"6":{"tf":1.0}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":4,"docs":{"10":{"tf":3.3166247903554},"12":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"v":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"a":{"df":0,"docs":{},"l":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"d":{"d":{"df":1,"docs":{"19":{"tf":1.7320508075688772}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":6,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0}}}}}}},"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.0}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"w":{"a":{"df":0,"docs":{},"y":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"y":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":3,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"i":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.6457513110645907}}}},"r":{"df":0,"docs":{},"o":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"r":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"11":{"tf":1.0},"20":{"tf":1.7320508075688772}}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"p":{"df":1,"docs":{"10":{"tf":1.0}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"i":{"c":{"df":9,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.4142135623730951},"13":{"tf":2.8284271247461903},"14":{"tf":1.0},"18":{"tf":1.4142135623730951},"20":{"tf":2.449489742783178},"6":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}},"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"21":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"c":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"m":{"df":2,"docs":{"0":{"tf":1.0},"17":{"tf":1.0}}}}},"t":{"df":1,"docs":{"4":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"a":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"v":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}}},"b":{"\"":{"b":{"a":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"n":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":2.0}}}}}}},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}}},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"13":{"tf":2.0}}},"df":0,"docs":{}}}}}},"a":{"c":{"df":0,"docs":{},"k":{"df":5,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"i":{"c":{"df":16,"docs":{"0":{"tf":1.0},"1":{"tf":1.7320508075688772},"10":{"tf":1.0},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0},"2":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.0}},"g":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.0},"18":{"tf":1.0}}}}},"h":{"a":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":3,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"6":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}}},"g":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"i":{"df":0,"docs":{},"g":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}},"n":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":2.0}}},"6":{"df":4,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.0}}},"3":{"df":1,"docs":{"17":{"tf":1.0}}},"4":{"8":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"17":{"tf":1.7320508075688772},"22":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":7,"docs":{"10":{"tf":4.123105625617661},"11":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":5.0990195135927845},"19":{"tf":1.0},"6":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"v":{"2":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":2,"docs":{"0":{"tf":2.23606797749979},"13":{"tf":1.4142135623730951}}},"l":{"df":2,"docs":{"12":{"tf":1.7320508075688772},"17":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"u":{"df":0,"docs":{},"n":{"d":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"a":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"o":{"a":{"d":{"c":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"12":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"u":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}},"i":{"df":0,"docs":{},"l":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"y":{"df":1,"docs":{"14":{"tf":1.0}}}},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"19":{"tf":2.23606797749979},"22":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"3":{"tf":1.0},"9":{"tf":1.4142135623730951}}}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}}}},"p":{"a":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"o":{"df":4,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":2.0}}}}},"df":1,"docs":{"8":{"tf":1.0}},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"1":{"tf":1.0},"15":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"k":{"df":4,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"i":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}},"o":{"d":{"df":0,"docs":{},"e":{"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":3.4641016151377544},"14":{"tf":2.449489742783178},"17":{"tf":1.7320508075688772},"18":{"tf":2.23606797749979},"19":{"tf":3.1622776601683795},"20":{"tf":1.7320508075688772},"4":{"tf":2.0},"6":{"tf":2.0},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":2.0},"20":{"tf":1.0},"22":{"tf":1.0}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":8,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":3.0},"21":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0}}},"x":{"df":1,"docs":{"11":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"0":{"tf":1.0}}}},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"22":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}},"o":{"df":0,"docs":{},"r":{"df":2,"docs":{"11":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"14":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"8":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}},"r":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":9,"docs":{"10":{"tf":3.7416573867739413},"11":{"tf":1.7320508075688772},"12":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":5.477225575051661},"18":{"tf":2.0},"19":{"tf":2.8284271247461903},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"r":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"20":{"tf":2.0}}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}},"i":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":9,"docs":{"10":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":2.0},"22":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"7":{"tf":1.7320508075688772},"8":{"tf":2.23606797749979},"9":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}}}},"c":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"6":{"tf":1.0}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"a":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"_":{"a":{"c":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":2.0},"14":{"tf":1.0},"18":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}},"i":{"df":1,"docs":{"17":{"tf":1.0}}},"l":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}}}}},"m":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}}},"s":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"b":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"19":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}}},"v":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"14":{"tf":1.0}}}}}}}},"i":{"a":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"13":{"tf":1.0}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"s":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"df":0,"docs":{}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"p":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}},"o":{"c":{"df":3,"docs":{"19":{"tf":1.4142135623730951},"3":{"tf":1.0},"4":{"tf":1.0}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.7320508075688772}}}}}}}},"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}},"p":{"d":{"df":0,"docs":{},"k":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":6,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.449489742783178},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":2.0},"6":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{".":{"df":0,"docs":{},"g":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}},"a":{"c":{"df":0,"docs":{},"h":{"df":5,"docs":{"0":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"6":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}},"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"y":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"d":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":2.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"17":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.7320508075688772},"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.23606797749979},"16":{"tf":1.7320508075688772},"17":{"tf":3.0}}}}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"19":{"tf":1.0}}}},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"n":{"c":{"a":{"df":0,"docs":{},"p":{"/":{"d":{"df":0,"docs":{},"e":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"s":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":3.3166247903554}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"17":{"tf":1.0},"20":{"tf":1.0}}}}}}},"r":{"df":0,"docs":{},"i":{"df":6,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"17":{"tf":2.449489742783178},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"20":{"tf":2.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"s":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":1,"docs":{"17":{"tf":1.4142135623730951}},"h":{"df":1,"docs":{"17":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"h":{"df":3,"docs":{"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":8,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":2.0},"16":{"tf":1.0},"17":{"tf":3.4641016151377544},"20":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0},"9":{"tf":1.0}}}}}}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"y":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}}}},"x":{"a":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":15,"docs":{"0":{"tf":1.4142135623730951},"10":{"tf":2.6457513110645907},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.4142135623730951},"15":{"tf":2.0},"16":{"tf":2.0},"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0},"20":{"tf":1.0}}}}},"df":0,"docs":{}},"p":{"a":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"!":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":3,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"20":{"tf":3.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.7320508075688772},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"f":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"s":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"20":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":5,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"i":{"b":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"d":{"df":6,"docs":{"10":{"tf":2.0},"17":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"4":{"tf":1.0}},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"4":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":1,"docs":{"17":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"(":{"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"2":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":4,"docs":{"16":{"tf":1.7320508075688772},"17":{"tf":2.6457513110645907},"19":{"tf":1.4142135623730951},"20":{"tf":2.0}}}}}},"n":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"11":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}},"d":{"df":3,"docs":{"17":{"tf":1.0},"20":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"h":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"13":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.7320508075688772}}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":10,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":2.6457513110645907},"18":{"tf":1.4142135623730951},"19":{"tf":2.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"16":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"o":{"c":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"6":{"tf":1.0}},"s":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":9,"docs":{"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"17":{"tf":1.7320508075688772},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"22":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"(":{"1":{"6":{"df":0,"docs":{},"w":{"0":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"1":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"b":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"<":{"1":{"6":{"df":3,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":2.8284271247461903},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"19":{"tf":2.0},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"8":{"tf":1.0}},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"13":{"tf":1.7320508075688772},"17":{"tf":3.0},"20":{"tf":2.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":2.0}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.4142135623730951}}}},"n":{"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"6":{"tf":1.4142135623730951}}}}}}}},"w":{"d":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"h":{"d":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":2,"docs":{"17":{"tf":1.7320508075688772},"19":{"tf":1.0}}},"df":0,"docs":{}}},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":8,"docs":{"10":{"tf":2.23606797749979},"14":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":2.23606797749979},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"t":{"df":2,"docs":{"1":{"tf":1.0},"20":{"tf":1.0}}}},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.0},"20":{"tf":1.0}}}}}},"o":{"df":5,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"o":{"d":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}},"r":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"15":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"21":{"tf":2.0},"22":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"y":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}}}}},"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}}},"r":{"df":2,"docs":{"0":{"tf":1.0},"14":{"tf":1.0}}},"w":{"df":0,"docs":{},"k":{"df":1,"docs":{"4":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"r":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{".":{"d":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{".":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":3,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951}}}},"df":2,"docs":{"17":{"tf":1.0},"4":{"tf":1.0}},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":9,"docs":{"10":{"tf":2.0},"12":{"tf":1.7320508075688772},"16":{"tf":1.0},"17":{"tf":3.605551275463989},"20":{"tf":1.0},"6":{"tf":2.0},"7":{"tf":1.0},"8":{"tf":2.23606797749979},"9":{"tf":3.605551275463989}},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.0}}}}}}}}}}},"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":10,"docs":{"1":{"tf":1.4142135623730951},"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.8284271247461903},"5":{"tf":2.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}}},"p":{"df":1,"docs":{"4":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":8,"docs":{"12":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.4142135623730951},"19":{"tf":1.0},"20":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"/":{"df":0,"docs":{},"s":{"df":0,"docs":{},"r":{"c":{"/":{"df":0,"docs":{},"p":{"4":{"/":{"b":{"df":0,"docs":{},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"/":{"c":{"df":0,"docs":{},"o":{"d":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.0}},"s":{":":{"/":{"/":{"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"u":{"b":{".":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"/":{"df":0,"docs":{},"o":{"df":0,"docs":{},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"s":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"p":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"3":{"tf":1.0}}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}}}}},"i":{".":{"df":1,"docs":{"19":{"tf":1.0}}},"/":{"df":0,"docs":{},"o":{"df":1,"docs":{"14":{"tf":1.0}}}},"c":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"df":2,"docs":{"16":{"tf":1.0},"17":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":1,"docs":{"16":{"tf":1.0}}}}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.6457513110645907},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.4142135623730951}}}}}}},"i":{"c":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"9":{"tf":1.0}}}}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"9":{"tf":1.0}}}}}}},"n":{"c":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"d":{"df":7,"docs":{"1":{"tf":1.0},"10":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"6":{"tf":1.0}}}}},"d":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"14":{"tf":1.0},"17":{"tf":1.0}}},"df":0,"docs":{}}}},"x":{"df":1,"docs":{"13":{"tf":1.0}}}},"i":{"c":{"df":1,"docs":{"17":{"tf":1.7320508075688772}}},"df":0,"docs":{}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":1,"docs":{"4":{"tf":1.4142135623730951}},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951}}}}}},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.0}}}}}}},"_":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":2.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"_":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":7,"docs":{"10":{"tf":2.449489742783178},"11":{"tf":1.0},"12":{"tf":2.23606797749979},"16":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.0},"6":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"(":{"&":{"df":0,"docs":{},"m":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"18":{"tf":1.0}}}}}},"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":4,"docs":{"10":{"tf":2.23606797749979},"12":{"tf":2.6457513110645907},"17":{"tf":2.6457513110645907},"6":{"tf":1.4142135623730951}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"14":{"tf":1.4142135623730951},"22":{"tf":1.0}}},"df":0,"docs":{}},"t":{"a":{"df":0,"docs":{},"l":{"df":4,"docs":{"1":{"tf":1.0},"2":{"tf":1.7320508075688772},"3":{"tf":1.7320508075688772},"4":{"tf":1.7320508075688772}}},"n":{"c":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":4,"docs":{"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.7320508075688772}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"17":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":1,"docs":{"8":{"tf":1.0}}},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"r":{"a":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.7320508075688772}}}},"df":0,"docs":{}},"df":0,"docs":{},"f":{"a":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"r":{"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"0":{"tf":1.0}},"t":{"df":2,"docs":{"0":{"tf":1.0},"5":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"c":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"p":{"df":2,"docs":{"10":{"tf":1.0},"9":{"tf":1.0}}},"s":{"df":0,"docs":{},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"t":{"'":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}}},"j":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"u":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"y":{"df":6,"docs":{"10":{"tf":2.6457513110645907},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.7320508075688772},"22":{"tf":1.4142135623730951}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":1,"docs":{"19":{"tf":1.0}},"l":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"g":{"df":1,"docs":{"0":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}}}}},"l":{"a":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"g":{"df":5,"docs":{"0":{"tf":1.0},"10":{"tf":2.23606797749979},"15":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"8":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":1,"docs":{"9":{"tf":1.0}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}},"v":{"df":2,"docs":{"10":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"t":{"'":{"df":8,"docs":{"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":2,"docs":{"13":{"tf":1.0},"17":{"tf":1.0}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":3,"docs":{"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}}},"i":{"b":{"df":0,"docs":{},"p":{"c":{"a":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.4142135623730951}}}}}}}}}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"13":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"t":{"df":0,"docs":{},"l":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}},"v":{"df":0,"docs":{},"e":{"df":2,"docs":{"13":{"tf":1.0},"15":{"tf":1.0}}}}},"o":{"a":{"d":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"i":{"c":{"df":5,"docs":{"10":{"tf":2.0},"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":2.449489742783178},"6":{"tf":1.0}}},"df":0,"docs":{}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"k":{"df":6,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":2,"docs":{"10":{"tf":1.7320508075688772},"16":{"tf":1.4142135623730951}}}}}},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"p":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}},"m":{"1":{"df":2,"docs":{"18":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951}}},"2":{"df":3,"docs":{"18":{"tf":1.7320508075688772},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"a":{"c":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"9":{"tf":1.0}},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.4142135623730951}}}}},"d":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"20":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":4,"docs":{"13":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}}},"df":4,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"18":{"tf":2.0}}}},"k":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":1.7320508075688772}}}},"n":{"a":{"df":0,"docs":{},"g":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"i":{"df":1,"docs":{"11":{"tf":1.0}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":1.0},"19":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}}},"p":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"t":{"c":{"df":0,"docs":{},"h":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":3.1622776601683795},"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"n":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"17":{"tf":2.0},"6":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"n":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"t":{"a":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"h":{"df":0,"docs":{},"o":{"d":{"df":4,"docs":{"13":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}}},"o":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"i":{"df":0,"docs":{},"f":{"df":1,"docs":{"19":{"tf":1.4142135623730951}},"i":{"df":2,"docs":{"10":{"tf":1.0},"17":{"tf":1.0}}}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"8":{"tf":1.0}}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"v":{"df":0,"docs":{},"e":{"df":1,"docs":{"9":{"tf":1.0}}}}},"u":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}}}}},"l":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}}}},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"19":{"tf":2.449489742783178},"6":{"tf":1.0},"8":{"tf":1.0}}}},"t":{"df":1,"docs":{"14":{"tf":1.0}},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"e":{"d":{"df":4,"docs":{"14":{"tf":1.0},"17":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}}}}},"x":{"df":0,"docs":{},"t":{"df":6,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"17":{"tf":1.0},"20":{"tf":2.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951}}}}},"o":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"9":{"tf":1.0}}},"h":{"df":1,"docs":{"14":{"tf":1.0}}},"i":{"c":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}}},"w":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"4":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}},"p":{"df":0,"docs":{},"u":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"(":{"0":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"1":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}},"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"u":{"df":0,"docs":{},"m":{"b":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":2,"docs":{"19":{"tf":1.0},"22":{"tf":1.7320508075688772}}}}}}},"o":{"b":{"df":0,"docs":{},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.7320508075688772}}}},"df":0,"docs":{}}},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}}}}},"d":{"d":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}},"df":1,"docs":{"4":{"tf":1.0}},"k":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"l":{"d":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"n":{"df":5,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.0},"19":{"tf":1.4142135623730951},"8":{"tf":1.0}},"t":{"df":0,"docs":{},"o":{"df":2,"docs":{"13":{"tf":1.0},"22":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{">":{"_":{"<":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"_":{"df":0,"docs":{},"p":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{">":{"_":{"<":{"df":0,"docs":{},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{">":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":4,"docs":{"14":{"tf":1.0},"16":{"tf":1.0},"19":{"tf":1.0},"9":{"tf":1.0}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"4":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}}},"r":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.0},"19":{"tf":1.4142135623730951},"22":{"tf":1.0}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"p":{"df":0,"docs":{},"f":{"df":1,"docs":{"10":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"v":{"df":2,"docs":{"16":{"tf":1.0},"19":{"tf":1.0}}}}}}},"t":{".":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":11,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":1.4142135623730951},"16":{"tf":1.4142135623730951},"17":{"tf":2.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"22":{"tf":1.0},"4":{"tf":1.4142135623730951},"5":{"tf":1.0},"6":{"tf":1.4142135623730951}},"g":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"s":{"df":0,"docs":{},"i":{"d":{"df":2,"docs":{"10":{"tf":1.0},"14":{"tf":1.0}}},"df":0,"docs":{}}}}},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"15":{"tf":1.0},"18":{"tf":1.4142135623730951},"22":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}},"x":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"/":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"p":{"4":{"_":{"df":0,"docs":{},"m":{"a":{"c":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{":":{":":{"df":0,"docs":{},"u":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"_":{"df":0,"docs":{},"p":{"4":{"!":{"(":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"c":{"df":1,"docs":{"14":{"tf":1.7320508075688772}}},"df":20,"docs":{"0":{"tf":1.7320508075688772},"1":{"tf":1.7320508075688772},"10":{"tf":2.8284271247461903},"11":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":2.6457513110645907},"15":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":2.23606797749979},"19":{"tf":2.449489742783178},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951},"4":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":1.7320508075688772},"7":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}},"a":{"c":{"df":0,"docs":{},"k":{"a":{"df":0,"docs":{},"g":{"df":2,"docs":{"11":{"tf":2.6457513110645907},"14":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"10":{"tf":1.0}}},"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}}},"df":14,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":3.872983346207417},"12":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.7320508075688772},"16":{"tf":2.449489742783178},"17":{"tf":3.1622776601683795},"18":{"tf":1.0},"20":{"tf":3.605551275463989},"22":{"tf":1.4142135623730951},"6":{"tf":3.0},"8":{"tf":1.7320508075688772},"9":{"tf":2.23606797749979}}}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":5,"docs":{"10":{"tf":3.3166247903554},"13":{"tf":1.4142135623730951},"17":{"tf":3.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.449489742783178}},"e":{"df":0,"docs":{},"r":{"_":{"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{},"s":{"df":7,"docs":{"10":{"tf":1.0},"11":{"tf":1.0},"12":{"tf":1.4142135623730951},"17":{"tf":2.0},"4":{"tf":1.7320508075688772},"6":{"tf":2.23606797749979},"9":{"tf":1.7320508075688772}},"e":{"df":0,"docs":{},"r":{"df":7,"docs":{"10":{"tf":2.6457513110645907},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.1622776601683795},"8":{"tf":1.0},"9":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"s":{"df":7,"docs":{"0":{"tf":1.0},"11":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"6":{"tf":1.4142135623730951}}},"t":{"df":1,"docs":{"16":{"tf":1.0}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"y":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"a":{"d":{"df":3,"docs":{"13":{"tf":2.0},"20":{"tf":1.0},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"17":{"tf":1.0}}}},"d":{"df":0,"docs":{},"v":{"df":0,"docs":{},"|":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"16":{"tf":1.0}},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.0},"18":{"tf":1.0}}}}}}}},"f":{"_":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{}},"h":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"y":{"1":{".":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"m":{"2":{"df":1,"docs":{"20":{"tf":1.7320508075688772}}},"3":{"df":1,"docs":{"20":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.0}}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"(":{"&":{"[":{"df":0,"docs":{},"t":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":2,"docs":{"13":{"tf":2.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}}}},"i":{"df":0,"docs":{},"e":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":7,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"13":{"tf":2.449489742783178},"14":{"tf":3.605551275463989},"18":{"tf":1.7320508075688772},"20":{"tf":1.7320508075688772},"9":{"tf":1.0}},"e":{".":{"a":{"d":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"w":{"d":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"b":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"y":{"(":{"\"":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"w":{"a":{"df":0,"docs":{},"r":{"d":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}},"df":0,"docs":{}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"_":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"19":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}}},"k":{"df":0,"docs":{},"t":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"a":{"c":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":3,"docs":{"12":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}},"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"6":{"tf":1.0}}}},"l":{"a":{"c":{"df":0,"docs":{},"e":{"df":3,"docs":{"14":{"tf":1.0},"18":{"tf":1.0},"6":{"tf":1.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":6,"docs":{"10":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.23606797749979},"18":{"tf":2.0},"19":{"tf":2.0},"20":{"tf":1.0}}}},"t":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"y":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{},"u":{"df":1,"docs":{"17":{"tf":1.0}}}},"o":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}},"p":{"df":1,"docs":{"17":{"tf":1.4142135623730951}},"u":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"r":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"v":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"17":{"tf":2.0}}},"df":0,"docs":{}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":1,"docs":{"17":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":8,"docs":{"10":{"tf":3.0},"12":{"tf":2.449489742783178},"13":{"tf":3.3166247903554},"16":{"tf":2.449489742783178},"17":{"tf":4.242640687119285},"19":{"tf":2.23606797749979},"20":{"tf":1.7320508075688772},"8":{"tf":2.23606797749979}},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":2,"docs":{"17":{"tf":1.4142135623730951},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"b":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"4":{"tf":1.0}}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.0},"4":{"tf":1.0}},"f":{"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"p":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"s":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":6,"docs":{"0":{"tf":1.0},"10":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.7320508075688772},"17":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":1,"docs":{"17":{"tf":1.0}}}}},"v":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"m":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"7":{"tf":1.0}}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}},"i":{"df":0,"docs":{},"t":{"df":2,"docs":{"10":{"tf":1.0},"8":{"tf":1.0}}}}},"n":{"df":0,"docs":{},"t":{"df":3,"docs":{"13":{"tf":1.0},"19":{"tf":1.0},"4":{"tf":1.4142135623730951}},"l":{"df":0,"docs":{},"n":{"df":1,"docs":{"19":{"tf":1.0}}}}}}},"o":{"b":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"c":{"df":0,"docs":{},"e":{"d":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":5,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":1.4142135623730951}}}}}},"d":{"df":0,"docs":{},"u":{"c":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":17,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"10":{"tf":4.123105625617661},"11":{"tf":1.0},"12":{"tf":2.23606797749979},"13":{"tf":3.7416573867739413},"14":{"tf":2.449489742783178},"16":{"tf":2.23606797749979},"17":{"tf":3.1622776601683795},"18":{"tf":2.8284271247461903},"19":{"tf":1.4142135623730951},"20":{"tf":2.0},"22":{"tf":1.7320508075688772},"5":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.0},"6":{"tf":1.0}}}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":2,"docs":{"10":{"tf":2.0},"17":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}}}},"v":{"df":0,"docs":{},"i":{"d":{"df":7,"docs":{"0":{"tf":1.0},"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.0},"21":{"tf":1.0},"8":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":4,"docs":{"10":{"tf":2.0},"18":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"h":{"df":1,"docs":{"1":{"tf":1.0}}}},"t":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"19":{"tf":1.0}}}}}}}}}},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"22":{"tf":1.0}}}},"t":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{},"e":{"a":{"d":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":1.4142135623730951}},"i":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}},"i":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"i":{"df":0,"docs":{},"v":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"d":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":5,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"16":{"tf":1.0},"20":{"tf":1.0},"22":{"tf":1.0}}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"17":{"tf":1.0}}}},"df":0,"docs":{}}}},"j":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}},"m":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"d":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}},"df":3,"docs":{"10":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"v":{"df":2,"docs":{"19":{"tf":1.0},"9":{"tf":1.0}}}}},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":2,"docs":{"8":{"tf":1.0},"9":{"tf":1.0}},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"4":{"tf":1.0}}}}}}}}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"df":0,"docs":{},"r":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"3":{"tf":1.0}}}}},"df":0,"docs":{}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"t":{"df":5,"docs":{"13":{"tf":1.0},"18":{"tf":1.7320508075688772},"19":{"tf":1.0},"20":{"tf":1.0},"9":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":2.23606797749979}}}}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"19":{"tf":1.0}}},"df":0,"docs":{}},"t":{"df":1,"docs":{"10":{"tf":2.23606797749979}}}}},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":2,"docs":{"20":{"tf":1.0},"22":{"tf":1.0}}}},"n":{"_":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"18":{"tf":1.0}}}}}}}}}},"df":2,"docs":{"18":{"tf":1.0},"20":{"tf":1.0}}}}}}},"df":10,"docs":{"10":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":2.8284271247461903},"14":{"tf":2.449489742783178},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.449489742783178},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"n":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"s":{"df":0,"docs":{},"t":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.7320508075688772},"13":{"tf":2.6457513110645907},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":2.449489742783178},"19":{"tf":1.7320508075688772},"3":{"tf":2.0},"4":{"tf":1.7320508075688772},"8":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"3":{"tf":1.4142135623730951}}}}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"2":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{},"v":{"(":{"df":0,"docs":{},"p":{"df":0,"docs":{},"h":{"df":0,"docs":{},"y":{"1":{".":{"df":0,"docs":{},"m":{"a":{"c":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"df":0,"docs":{}}}}},"s":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}}},"n":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}}}}},"w":{"df":1,"docs":{"10":{"tf":1.0}}}},"c":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}}},"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":4,"docs":{"10":{"tf":1.0},"13":{"tf":2.0},"19":{"tf":1.7320508075688772},"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":2.0},"20":{"tf":1.0},"6":{"tf":1.4142135623730951},"8":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":8,"docs":{"13":{"tf":1.0},"14":{"tf":1.0},"16":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":2.23606797749979},"3":{"tf":1.0},"6":{"tf":1.7320508075688772}}},"l":{"df":0,"docs":{},"f":{"df":1,"docs":{"14":{"tf":1.0}}}},"m":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}},"n":{"d":{"df":5,"docs":{"12":{"tf":1.0},"13":{"tf":1.7320508075688772},"16":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.23606797749979}}},"df":0,"docs":{},"s":{"df":1,"docs":{"17":{"tf":1.0}}}},"p":{"a":{"df":0,"docs":{},"r":{"df":2,"docs":{"14":{"tf":1.0},"19":{"tf":1.0}}}},"df":0,"docs":{}},"q":{"df":0,"docs":{},"u":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"c":{"df":1,"docs":{"10":{"tf":1.0}}},"df":0,"docs":{}}}}},"r":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}}},"df":1,"docs":{"15":{"tf":1.0}}}},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}}},"t":{"df":11,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"13":{"tf":1.0},"14":{"tf":1.0},"15":{"tf":1.0},"16":{"tf":1.4142135623730951},"17":{"tf":2.6457513110645907},"18":{"tf":1.0},"19":{"tf":1.7320508075688772},"6":{"tf":2.0},"9":{"tf":1.0}},"u":{"df":0,"docs":{},"p":{"df":1,"docs":{"1":{"tf":1.0}}}},"v":{"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":1,"docs":{"9":{"tf":1.7320508075688772}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"h":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":1,"docs":{"10":{"tf":1.0}}}}},"df":1,"docs":{"3":{"tf":1.0}},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"3":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"w":{"df":7,"docs":{"11":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"18":{"tf":1.0},"4":{"tf":2.8284271247461903},"6":{"tf":1.0}},"n":{"df":1,"docs":{"6":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"df":0,"docs":{},"r":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"r":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"8":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{}}},"p":{"df":0,"docs":{},"l":{"df":6,"docs":{"0":{"tf":1.0},"1":{"tf":1.0},"10":{"tf":2.0},"16":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.4142135623730951}},"i":{"df":3,"docs":{"16":{"tf":1.0},"3":{"tf":1.0},"6":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"l":{"df":4,"docs":{"11":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":2.0},"20":{"tf":1.0}}}}},"z":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"i":{"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"(":{"2":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"20":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":6,"docs":{"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":3.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0},"20":{"tf":1.4142135623730951}}}}},"w":{"a":{"df":0,"docs":{},"r":{"df":1,"docs":{"13":{"tf":1.0}}}},"df":0,"docs":{}}}},"m":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}},"w":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"6":{"tf":1.0}}}},"df":0,"docs":{}}}}},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"u":{"df":0,"docs":{},"r":{"c":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}},"p":{"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"k":{"df":1,"docs":{"22":{"tf":1.0}}}},"c":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}},"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0}}}}}},"df":0,"docs":{}}},"r":{"c":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"s":{"df":0,"docs":{},"f":{"df":1,"docs":{"3":{"tf":1.0}}}},"t":{"a":{"c":{"df":0,"docs":{},"k":{"df":2,"docs":{"17":{"tf":1.0},"9":{"tf":1.0}}}},"df":0,"docs":{},"n":{"d":{"df":1,"docs":{"14":{"tf":2.0}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"t":{"df":8,"docs":{"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0},"5":{"tf":1.0},"6":{"tf":2.0}}}},"t":{"df":0,"docs":{},"e":{"df":4,"docs":{"10":{"tf":1.7320508075688772},"12":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"6":{"tf":3.4641016151377544}},"l":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}},"u":{"c":{"df":0,"docs":{},"t":{"df":5,"docs":{"12":{"tf":1.7320508075688772},"13":{"tf":1.0},"17":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":3.0}},"u":{"df":0,"docs":{},"r":{"df":6,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.4142135623730951}}}}}},"df":0,"docs":{}}}},"u":{"c":{"c":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}}}}},"df":0,"docs":{},"h":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{},"g":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}}}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.0}}},"df":0,"docs":{}}},"df":6,"docs":{"16":{"tf":2.8284271247461903},"17":{"tf":2.23606797749979},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.7320508075688772},"8":{"tf":1.0}},"e":{"df":0,"docs":{},"s":{"/":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"/":{"a":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"x":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{}}},"s":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"m":{"df":3,"docs":{"10":{"tf":1.0},"14":{"tf":1.4142135623730951},"18":{"tf":1.0}}}}}}}},"t":{"a":{"b":{"df":0,"docs":{},"l":{"df":8,"docs":{"10":{"tf":4.69041575982343},"12":{"tf":1.0},"16":{"tf":2.0},"17":{"tf":3.3166247903554},"18":{"tf":1.7320508075688772},"19":{"tf":3.3166247903554},"20":{"tf":1.4142135623730951},"22":{"tf":1.4142135623730951}},"e":{"_":{"df":0,"docs":{},"n":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"19":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":1,"docs":{"20":{"tf":1.0}}}}}}}}}},"df":0,"docs":{},"g":{"df":2,"docs":{"17":{"tf":1.7320508075688772},"20":{"tf":1.0}}},"k":{"df":0,"docs":{},"e":{"df":9,"docs":{"1":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":2.449489742783178},"20":{"tf":1.0},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"(":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}},"/":{"d":{"df":0,"docs":{},"e":{"b":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"/":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"13":{"tf":1.0}}}}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"20":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.7320508075688772},"4":{"tf":1.7320508075688772}}}}}},"s":{"df":0,"docs":{},"k":{"df":1,"docs":{"10":{"tf":1.0}}}}},"b":{"df":0,"docs":{},"l":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"10":{"tf":1.0},"12":{"tf":1.0}}}},"c":{"df":0,"docs":{},"p":{"df":1,"docs":{"9":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"3":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"t":{"df":4,"docs":{"13":{"tf":1.4142135623730951},"14":{"tf":1.4142135623730951},"17":{"tf":1.4142135623730951},"20":{"tf":2.449489742783178}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"/":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}},"s":{":":{":":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{":":{":":{"df":0,"docs":{},"{":{"df":0,"docs":{},"r":{"df":0,"docs":{},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.4142135623730951},"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"{":{"df":0,"docs":{},"e":{"df":0,"docs":{},"x":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"c":{"df":0,"docs":{},"t":{"_":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}},"df":0,"docs":{}}}},"df":0,"docs":{}}},"df":0,"docs":{}}}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"h":{"a":{"df":0,"docs":{},"t":{"'":{"df":1,"docs":{"4":{"tf":1.0}}},"df":0,"docs":{}}},"df":1,"docs":{"21":{"tf":1.0}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":7,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.4142135623730951},"3":{"tf":1.0}}},"k":{"df":1,"docs":{"17":{"tf":1.0}}}},"r":{"d":{"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":3,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"6":{"tf":1.4142135623730951}}}},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.0}}}}}},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"e":{"df":1,"docs":{"20":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"g":{"df":0,"docs":{},"h":{"df":10,"docs":{"0":{"tf":1.4142135623730951},"1":{"tf":1.0},"10":{"tf":1.7320508075688772},"12":{"tf":1.0},"13":{"tf":2.0},"14":{"tf":1.4142135623730951},"15":{"tf":1.0},"18":{"tf":1.0},"20":{"tf":2.8284271247461903},"9":{"tf":1.0}}}}}}}},"i":{"df":1,"docs":{"11":{"tf":1.0}},"m":{"df":0,"docs":{},"e":{"df":3,"docs":{"15":{"tf":1.0},"17":{"tf":1.0},"19":{"tf":1.0}}}}},"l":{"df":0,"docs":{},"s":{"df":0,"docs":{},"v":{"1":{".":{"2":{"df":1,"docs":{"3":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}}}},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":2,"docs":{"12":{"tf":1.0},"13":{"tf":1.0}}}}}},"k":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}},"o":{"df":0,"docs":{},"l":{"c":{"df":0,"docs":{},"h":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"1":{"tf":1.0}}}}},"df":0,"docs":{}}},"df":2,"docs":{"3":{"tf":1.0},"4":{"tf":1.0}}}},"p":{"df":3,"docs":{"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.0}}}},"r":{"a":{"df":0,"docs":{},"f":{"df":0,"docs":{},"f":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"14":{"tf":1.0}}},"df":0,"docs":{}}}},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"f":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"m":{"df":1,"docs":{"22":{"tf":1.0}}}}}},"i":{"df":0,"docs":{},"t":{"df":4,"docs":{"12":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.7320508075688772},"6":{"tf":3.0}}}},"l":{"a":{"df":0,"docs":{},"t":{"df":2,"docs":{"13":{"tf":1.0},"18":{"tf":1.0}}}},"df":0,"docs":{}},"m":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":1,"docs":{"13":{"tf":1.0}}}}}}}},"df":0,"docs":{},"e":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{},"e":{"df":1,"docs":{"4":{"tf":1.0}}}},"u":{"df":0,"docs":{},"e":{"df":1,"docs":{"17":{"tf":3.1622776601683795}}}}},"u":{"df":0,"docs":{},"n":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"w":{"df":0,"docs":{},"o":{"df":8,"docs":{"10":{"tf":1.0},"13":{"tf":1.0},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"20":{"tf":1.0},"7":{"tf":1.0}}}},"x":{"df":0,"docs":{},"f":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"e":{":":{":":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"w":{"df":1,"docs":{"20":{"tf":1.0}},"v":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"df":0,"docs":{}},"df":2,"docs":{"13":{"tf":1.7320508075688772},"18":{"tf":1.0}}}}},"df":0,"docs":{}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":8,"docs":{"10":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.0},"19":{"tf":1.0},"22":{"tf":1.7320508075688772},"6":{"tf":1.7320508075688772},"7":{"tf":2.0},"8":{"tf":2.0}}},"i":{"c":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"11":{"tf":1.0},"6":{"tf":1.0},"9":{"tf":1.0}}},"df":0,"docs":{}}}}},"u":{"8":{";":{"6":{"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"df":0,"docs":{}},"df":1,"docs":{"20":{"tf":1.4142135623730951}}},"df":0,"docs":{},"n":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"17":{"tf":1.0}}}}}}}},"df":0,"docs":{}}}},"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":1,"docs":{"19":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"x":{"/":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"u":{"df":0,"docs":{},"x":{"df":1,"docs":{"3":{"tf":1.0}}}}}}}},"df":0,"docs":{}}},"k":{"df":0,"docs":{},"n":{"df":0,"docs":{},"o":{"df":0,"docs":{},"w":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"p":{"df":0,"docs":{},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"m":{"df":2,"docs":{"13":{"tf":1.0},"20":{"tf":1.0}}}}}}},"s":{"df":0,"docs":{},"i":{"df":0,"docs":{},"g":{"df":0,"docs":{},"n":{"df":1,"docs":{"8":{"tf":1.0}}}}}},"t":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}}}}},"p":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"m":{"df":1,"docs":{"9":{"tf":1.0}}}}},"d":{"a":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}},"df":7,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"14":{"tf":1.0},"17":{"tf":2.0},"18":{"tf":1.0},"19":{"tf":1.4142135623730951},"6":{"tf":1.0}}},"s":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":13,"docs":{"0":{"tf":1.7320508075688772},"10":{"tf":2.23606797749979},"12":{"tf":1.4142135623730951},"13":{"tf":3.1622776601683795},"14":{"tf":3.872983346207417},"15":{"tf":1.0},"17":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"19":{"tf":1.7320508075688772},"20":{"tf":1.0},"3":{"tf":1.0},"4":{"tf":1.0},"8":{"tf":1.0}},"e":{"_":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"18":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"6":{"tf":1.0}}}}}},"v":{"0":{".":{"1":{".":{"0":{"df":1,"docs":{"13":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"df":0,"docs":{}},"a":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"d":{"df":3,"docs":{"17":{"tf":1.0},"19":{"tf":1.0},"20":{"tf":1.0}}},"df":0,"docs":{}},"u":{"df":7,"docs":{"10":{"tf":1.4142135623730951},"13":{"tf":1.0},"17":{"tf":2.0},"19":{"tf":1.4142135623730951},"4":{"tf":1.0},"8":{"tf":1.7320508075688772},"9":{"tf":1.0}}}},"r":{"df":0,"docs":{},"i":{"a":{"b":{"df":0,"docs":{},"l":{"df":1,"docs":{"17":{"tf":2.0}}}},"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.0}}}}},"df":1,"docs":{"6":{"tf":1.0}},"o":{"df":0,"docs":{},"u":{"df":2,"docs":{"10":{"tf":1.0},"21":{"tf":1.0}}}}}}},"df":1,"docs":{"4":{"tf":1.0}},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"i":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"16":{"tf":1.0}}},"s":{"a":{"df":1,"docs":{"12":{"tf":1.0}}},"df":0,"docs":{},"i":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":1,"docs":{"4":{"tf":1.4142135623730951}}}}}}}},"i":{"a":{"df":1,"docs":{"16":{"tf":1.0}}},"c":{"df":0,"docs":{},"e":{"df":1,"docs":{"12":{"tf":1.0}}}},"d":{"df":4,"docs":{"16":{"tf":2.0},"17":{"tf":4.242640687119285},"19":{"tf":1.0},"20":{"tf":1.7320508075688772}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":0,"docs":{},"u":{"a":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"18":{"tf":1.4142135623730951},"20":{"tf":1.0}}}},"df":0,"docs":{}}}}},"l":{"a":{"df":0,"docs":{},"n":{".":{"a":{"df":0,"docs":{},"p":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":0,"docs":{},"y":{"(":{"df":0,"docs":{},"e":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"s":{".":{"df":0,"docs":{},"p":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"t":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}}}}}},"df":0,"docs":{}}}}}}}}},"df":0,"docs":{}}}}}},"df":0,"docs":{}},"_":{"df":0,"docs":{},"h":{"df":1,"docs":{"17":{"tf":1.4142135623730951}}},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"17":{"tf":3.605551275463989}}}},"s":{"df":0,"docs":{},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"df":5,"docs":{"16":{"tf":2.6457513110645907},"17":{"tf":5.196152422706632},"18":{"tf":1.4142135623730951},"19":{"tf":2.23606797749979},"20":{"tf":2.449489742783178}}}},"df":0,"docs":{}}},"w":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"df":2,"docs":{"14":{"tf":1.0},"6":{"tf":1.0}}}},"y":{"df":4,"docs":{"10":{"tf":1.4142135623730951},"14":{"tf":2.0},"19":{"tf":1.0},"22":{"tf":1.0}}}},"df":0,"docs":{},"e":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":10,"docs":{"10":{"tf":1.0},"12":{"tf":1.0},"13":{"tf":1.4142135623730951},"16":{"tf":1.0},"17":{"tf":1.7320508075688772},"18":{"tf":1.7320508075688772},"3":{"tf":1.4142135623730951},"6":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.0}}}},"r":{"df":1,"docs":{"4":{"tf":1.0}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":3,"docs":{"14":{"tf":1.4142135623730951},"17":{"tf":1.0},"8":{"tf":1.0}}}},"n":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"e":{"df":0,"docs":{},"v":{"df":1,"docs":{"14":{"tf":1.0}}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"i":{"d":{"df":0,"docs":{},"t":{"df":0,"docs":{},"h":{"df":1,"docs":{"10":{"tf":1.4142135623730951}}}}},"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}},"r":{"df":0,"docs":{},"e":{"df":2,"docs":{"10":{"tf":1.4142135623730951},"22":{"tf":1.7320508075688772}}}},"t":{"df":0,"docs":{},"h":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}},"o":{"df":0,"docs":{},"u":{"df":0,"docs":{},"t":{"df":1,"docs":{"10":{"tf":1.0}}}}}}}},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"k":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"18":{"tf":1.0}}},"l":{"d":{".":{"df":0,"docs":{},"p":{"4":{"df":1,"docs":{"13":{"tf":1.4142135623730951}}},"df":0,"docs":{}}},"df":10,"docs":{"1":{"tf":1.4142135623730951},"10":{"tf":1.0},"11":{"tf":1.4142135623730951},"12":{"tf":1.4142135623730951},"13":{"tf":2.449489742783178},"5":{"tf":2.0},"6":{"tf":1.0},"7":{"tf":1.0},"8":{"tf":1.4142135623730951},"9":{"tf":1.4142135623730951}}},"df":0,"docs":{}}}},"r":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"df":0,"docs":{},"e":{"df":6,"docs":{"1":{"tf":1.0},"10":{"tf":1.4142135623730951},"14":{"tf":1.0},"17":{"tf":1.4142135623730951},"19":{"tf":1.0},"4":{"tf":1.0}}},"t":{"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"df":1,"docs":{"10":{"tf":1.0}}}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"g":{"df":1,"docs":{"20":{"tf":1.0}}}}}}},"x":{"4":{"c":{"df":8,"docs":{"0":{"tf":2.23606797749979},"1":{"tf":1.0},"13":{"tf":1.7320508075688772},"14":{"tf":4.0},"15":{"tf":1.0},"19":{"tf":1.0},"21":{"tf":1.0},"4":{"tf":2.8284271247461903}}},"df":0,"docs":{}},"d":{"df":0,"docs":{},"p":{"df":1,"docs":{"14":{"tf":1.0}}}},"df":1,"docs":{"19":{"tf":1.4142135623730951}}},"y":{"df":0,"docs":{},"o":{"df":0,"docs":{},"u":{"'":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":2,"docs":{"19":{"tf":1.0},"8":{"tf":1.0}}}}},"df":0,"docs":{}}}},"z":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":2,"docs":{"1":{"tf":1.0},"17":{"tf":1.0}}}}},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"/":{"c":{"df":0,"docs":{},"o":{"df":0,"docs":{},"n":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{}}}}},"df":0,"docs":{}},"df":0,"docs":{}}}}}}}},"title":{"root":{"b":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"i":{"c":{"df":1,"docs":{"1":{"tf":1.0}}},"df":0,"docs":{}}}},"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"c":{"df":0,"docs":{},"k":{"df":1,"docs":{"10":{"tf":1.0}}}},"df":0,"docs":{}}},"o":{"df":0,"docs":{},"o":{"df":0,"docs":{},"k":{"df":1,"docs":{"0":{"tf":1.0}}}}}},"c":{"a":{"df":0,"docs":{},"s":{"df":0,"docs":{},"e":{"df":1,"docs":{"14":{"tf":1.0}}}}},"df":0,"docs":{},"o":{"d":{"df":0,"docs":{},"e":{"df":2,"docs":{"19":{"tf":1.0},"20":{"tf":1.0}}}},"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"i":{"df":0,"docs":{},"l":{"df":1,"docs":{"13":{"tf":1.0}}}}}},"n":{"df":0,"docs":{},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"l":{"df":3,"docs":{"10":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0}}}}}}}}},"d":{"a":{"df":0,"docs":{},"t":{"a":{"df":2,"docs":{"17":{"tf":1.0},"7":{"tf":1.0}}},"df":0,"docs":{}}},"df":0,"docs":{}},"df":0,"docs":{},"e":{"df":0,"docs":{},"n":{"d":{"df":0,"docs":{},"i":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"22":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{}},"x":{"a":{"df":0,"docs":{},"m":{"df":0,"docs":{},"p":{"df":0,"docs":{},"l":{"df":1,"docs":{"15":{"tf":1.0}}}}}},"df":0,"docs":{}}},"f":{"df":0,"docs":{},"u":{"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":1,"docs":{"12":{"tf":1.0}}}}}},"g":{"df":0,"docs":{},"u":{"df":0,"docs":{},"i":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"l":{"df":0,"docs":{},"i":{"df":0,"docs":{},"n":{"df":1,"docs":{"21":{"tf":1.0}}}}}}},"df":0,"docs":{}}}},"h":{"df":0,"docs":{},"e":{"a":{"d":{"df":0,"docs":{},"e":{"df":0,"docs":{},"r":{"df":1,"docs":{"9":{"tf":1.0}}}}},"df":0,"docs":{}},"df":0,"docs":{},"l":{"df":0,"docs":{},"l":{"df":0,"docs":{},"o":{"df":1,"docs":{"5":{"tf":1.0}}}}}}},"i":{"df":0,"docs":{},"n":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"a":{"df":0,"docs":{},"l":{"df":1,"docs":{"2":{"tf":1.0}}}},"df":0,"docs":{}}}}},"p":{"4":{"df":1,"docs":{"17":{"tf":1.0}}},"a":{"c":{"df":0,"docs":{},"k":{"a":{"df":0,"docs":{},"g":{"df":1,"docs":{"11":{"tf":1.0}}}},"df":0,"docs":{}}},"df":0,"docs":{},"r":{"df":0,"docs":{},"s":{"df":1,"docs":{"6":{"tf":1.0}}}}},"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":0,"docs":{},"e":{"df":3,"docs":{"17":{"tf":1.0},"18":{"tf":1.0},"19":{"tf":1.0}}}}},"df":0,"docs":{}},"r":{"df":0,"docs":{},"o":{"df":0,"docs":{},"g":{"df":0,"docs":{},"r":{"a":{"df":0,"docs":{},"m":{"df":3,"docs":{"12":{"tf":1.0},"17":{"tf":1.0},"18":{"tf":1.0}}}},"df":0,"docs":{}}}}}},"r":{"df":0,"docs":{},"u":{"df":0,"docs":{},"n":{"df":1,"docs":{"13":{"tf":1.0}}},"s":{"df":0,"docs":{},"t":{"df":2,"docs":{"18":{"tf":1.0},"3":{"tf":1.0}}}}}},"s":{"df":0,"docs":{},"o":{"df":0,"docs":{},"f":{"df":0,"docs":{},"t":{"df":0,"docs":{},"n":{"df":0,"docs":{},"p":{"df":0,"docs":{},"u":{"df":1,"docs":{"14":{"tf":1.0}}}}}}}},"t":{"df":0,"docs":{},"r":{"df":0,"docs":{},"u":{"c":{"df":0,"docs":{},"t":{"df":1,"docs":{"8":{"tf":1.0}}}},"df":0,"docs":{}}}},"w":{"df":0,"docs":{},"i":{"df":0,"docs":{},"t":{"c":{"df":0,"docs":{},"h":{"df":1,"docs":{"16":{"tf":1.0}}}},"df":0,"docs":{}}}}},"t":{"a":{"df":0,"docs":{},"r":{"df":0,"docs":{},"g":{"df":0,"docs":{},"e":{"df":0,"docs":{},"t":{"df":1,"docs":{"14":{"tf":1.0}}}}}}},"df":0,"docs":{},"e":{"df":0,"docs":{},"s":{"df":0,"docs":{},"t":{"df":1,"docs":{"20":{"tf":1.0}}}}},"y":{"df":0,"docs":{},"p":{"df":0,"docs":{},"e":{"df":1,"docs":{"7":{"tf":1.0}}}}}},"u":{"df":0,"docs":{},"s":{"df":1,"docs":{"14":{"tf":1.0}}}},"v":{"df":0,"docs":{},"l":{"a":{"df":0,"docs":{},"n":{"df":1,"docs":{"16":{"tf":1.0}}}},"df":0,"docs":{}}},"w":{"df":0,"docs":{},"o":{"df":0,"docs":{},"r":{"df":0,"docs":{},"l":{"d":{"df":1,"docs":{"5":{"tf":1.0}}},"df":0,"docs":{}}}}},"x":{"4":{"c":{"df":3,"docs":{"0":{"tf":1.0},"14":{"tf":1.0},"4":{"tf":1.0}}},"df":0,"docs":{}},"df":0,"docs":{}}}}},"lang":"English","pipeline":["trimmer","stopWordFilter","stemmer"],"ref":"id","version":"0.9.5"},"results_options":{"limit_results":30,"teaser_word_count":30},"search_options":{"bool":"OR","expand":true,"fields":{"body":{"boost":1},"breadcrumbs":{"boost":1},"title":{"boost":2}}}} \ No newline at end of file diff --git a/book/tomorrow-night.css b/book/tomorrow-night.css new file mode 100644 index 00000000..81fe276e --- /dev/null +++ b/book/tomorrow-night.css @@ -0,0 +1,102 @@ +/* Tomorrow Night Theme */ +/* https://github.com/jmblog/color-themes-for-highlightjs */ +/* Original theme - https://github.com/chriskempson/tomorrow-theme */ +/* https://github.com/jmblog/color-themes-for-highlightjs */ + +/* Tomorrow Comment */ +.hljs-comment { + color: #969896; +} + +/* Tomorrow Red */ +.hljs-variable, +.hljs-attribute, +.hljs-tag, +.hljs-regexp, +.ruby .hljs-constant, +.xml .hljs-tag .hljs-title, +.xml .hljs-pi, +.xml .hljs-doctype, +.html .hljs-doctype, +.css .hljs-id, +.css .hljs-class, +.css .hljs-pseudo { + color: #cc6666; +} + +/* Tomorrow Orange */ +.hljs-number, +.hljs-preprocessor, +.hljs-pragma, +.hljs-built_in, +.hljs-literal, +.hljs-params, +.hljs-constant { + color: #de935f; +} + +/* Tomorrow Yellow */ +.ruby .hljs-class .hljs-title, +.css .hljs-rule .hljs-attribute { + color: #f0c674; +} + +/* Tomorrow Green */ +.hljs-string, +.hljs-value, +.hljs-inheritance, +.hljs-header, +.hljs-name, +.ruby .hljs-symbol, +.xml .hljs-cdata { + color: #b5bd68; +} + +/* Tomorrow Aqua */ +.hljs-title, +.css .hljs-hexcolor { + color: #8abeb7; +} + +/* Tomorrow Blue */ +.hljs-function, +.python .hljs-decorator, +.python .hljs-title, +.ruby .hljs-function .hljs-title, +.ruby .hljs-title .hljs-keyword, +.perl .hljs-sub, +.javascript .hljs-title, +.coffeescript .hljs-title { + color: #81a2be; +} + +/* Tomorrow Purple */ +.hljs-keyword, +.javascript .hljs-function { + color: #b294bb; +} + +.hljs { + display: block; + overflow-x: auto; + background: #1d1f21; + color: #c5c8c6; +} + +.coffeescript .javascript, +.javascript .xml, +.tex .hljs-formula, +.xml .javascript, +.xml .vbscript, +.xml .css, +.xml .hljs-cdata { + opacity: 0.5; +} + +.hljs-addition { + color: #718c00; +} + +.hljs-deletion { + color: #c82829; +} diff --git a/crates.js b/crates.js new file mode 100644 index 00000000..309aebad --- /dev/null +++ b/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["hello_world","p4","p4_macro","p4_macro_test","p4_rust","p4rs","sidecar_lite","tests","vlan_switch","x4c","x4c_error_codes"]; \ No newline at end of file diff --git a/hello_world/all.html b/hello_world/all.html new file mode 100644 index 00000000..7bbdb5fd --- /dev/null +++ b/hello_world/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/hello_world/fn._hello_pipeline_create.html b/hello_world/fn._hello_pipeline_create.html new file mode 100644 index 00000000..ecde4ff5 --- /dev/null +++ b/hello_world/fn._hello_pipeline_create.html @@ -0,0 +1,5 @@ +_hello_pipeline_create in hello_world - Rust +
#[no_mangle]
+pub extern "C" fn _hello_pipeline_create(
+    radix: u16
+) -> *mut dyn Pipeline
\ No newline at end of file diff --git a/hello_world/fn.egress_apply.html b/hello_world/fn.egress_apply.html new file mode 100644 index 00000000..59b37466 --- /dev/null +++ b/hello_world/fn.egress_apply.html @@ -0,0 +1,6 @@ +egress_apply in hello_world - Rust +

Function hello_world::egress_apply

source ·
pub fn egress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t
+)
\ No newline at end of file diff --git a/hello_world/fn.ingress_action_drop.html b/hello_world/fn.ingress_action_drop.html new file mode 100644 index 00000000..79d12393 --- /dev/null +++ b/hello_world/fn.ingress_action_drop.html @@ -0,0 +1,6 @@ +ingress_action_drop in hello_world - Rust +
pub fn ingress_action_drop(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t
+)
\ No newline at end of file diff --git a/hello_world/fn.ingress_action_forward.html b/hello_world/fn.ingress_action_forward.html new file mode 100644 index 00000000..db22907e --- /dev/null +++ b/hello_world/fn.ingress_action_forward.html @@ -0,0 +1,7 @@ +ingress_action_forward in hello_world - Rust +
pub fn ingress_action_forward(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    port: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/hello_world/fn.ingress_apply.html b/hello_world/fn.ingress_apply.html new file mode 100644 index 00000000..f1472956 --- /dev/null +++ b/hello_world/fn.ingress_apply.html @@ -0,0 +1,7 @@ +ingress_apply in hello_world - Rust +

Function hello_world::ingress_apply

source ·
pub fn ingress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    tbl: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/hello_world/fn.ingress_tbl.html b/hello_world/fn.ingress_tbl.html new file mode 100644 index 00000000..41d10ca4 --- /dev/null +++ b/hello_world/fn.ingress_tbl.html @@ -0,0 +1,3 @@ +ingress_tbl in hello_world - Rust +

Function hello_world::ingress_tbl

source ·
pub fn ingress_tbl(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/hello_world/fn.main.html b/hello_world/fn.main.html new file mode 100644 index 00000000..574ae646 --- /dev/null +++ b/hello_world/fn.main.html @@ -0,0 +1,2 @@ +main in hello_world - Rust +

Function hello_world::main

source ·
pub(crate) fn main() -> Result<(), Error>
\ No newline at end of file diff --git a/hello_world/fn.parse_finish.html b/hello_world/fn.parse_finish.html new file mode 100644 index 00000000..063fa0c1 --- /dev/null +++ b/hello_world/fn.parse_finish.html @@ -0,0 +1,6 @@ +parse_finish in hello_world - Rust +

Function hello_world::parse_finish

source ·
pub fn parse_finish(
+    pkt: &mut packet_in<'_>,
+    headers: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/hello_world/fn.parse_start.html b/hello_world/fn.parse_start.html new file mode 100644 index 00000000..951fd372 --- /dev/null +++ b/hello_world/fn.parse_start.html @@ -0,0 +1,6 @@ +parse_start in hello_world - Rust +

Function hello_world::parse_start

source ·
pub fn parse_start(
+    pkt: &mut packet_in<'_>,
+    headers: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/hello_world/index.html b/hello_world/index.html new file mode 100644 index 00000000..cad29aae --- /dev/null +++ b/hello_world/index.html @@ -0,0 +1,3 @@ +hello_world - Rust +
\ No newline at end of file diff --git a/hello_world/sidebar-items.js b/hello_world/sidebar-items.js new file mode 100644 index 00000000..61d85086 --- /dev/null +++ b/hello_world/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["_hello_pipeline_create","egress_apply","ingress_action_drop","ingress_action_forward","ingress_apply","ingress_tbl","main","parse_finish","parse_start"],"mod":["softnpu_provider"],"struct":["egress_metadata_t","ethernet_h","headers_t","ingress_metadata_t","main_pipeline"]}; \ No newline at end of file diff --git a/hello_world/softnpu_provider/index.html b/hello_world/softnpu_provider/index.html new file mode 100644 index 00000000..c6841379 --- /dev/null +++ b/hello_world/softnpu_provider/index.html @@ -0,0 +1,2 @@ +hello_world::softnpu_provider - Rust +
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.action!.html b/hello_world/softnpu_provider/macro.action!.html new file mode 100644 index 00000000..d4ab696b --- /dev/null +++ b/hello_world/softnpu_provider/macro.action!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.action.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.action.html b/hello_world/softnpu_provider/macro.action.html new file mode 100644 index 00000000..440891e4 --- /dev/null +++ b/hello_world/softnpu_provider/macro.action.html @@ -0,0 +1,5 @@ +action in hello_world::softnpu_provider - Rust +
macro_rules! action {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.control_apply!.html b/hello_world/softnpu_provider/macro.control_apply!.html new file mode 100644 index 00000000..30ff9a1c --- /dev/null +++ b/hello_world/softnpu_provider/macro.control_apply!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_apply.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.control_apply.html b/hello_world/softnpu_provider/macro.control_apply.html new file mode 100644 index 00000000..aad75e26 --- /dev/null +++ b/hello_world/softnpu_provider/macro.control_apply.html @@ -0,0 +1,5 @@ +control_apply in hello_world::softnpu_provider - Rust +
macro_rules! control_apply {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.control_table_hit!.html b/hello_world/softnpu_provider/macro.control_table_hit!.html new file mode 100644 index 00000000..b2c3113d --- /dev/null +++ b/hello_world/softnpu_provider/macro.control_table_hit!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_table_hit.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.control_table_hit.html b/hello_world/softnpu_provider/macro.control_table_hit.html new file mode 100644 index 00000000..728267b3 --- /dev/null +++ b/hello_world/softnpu_provider/macro.control_table_hit.html @@ -0,0 +1,5 @@ +control_table_hit in hello_world::softnpu_provider - Rust +
macro_rules! control_table_hit {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.control_table_miss!.html b/hello_world/softnpu_provider/macro.control_table_miss!.html new file mode 100644 index 00000000..6c9107c1 --- /dev/null +++ b/hello_world/softnpu_provider/macro.control_table_miss!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_table_miss.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.control_table_miss.html b/hello_world/softnpu_provider/macro.control_table_miss.html new file mode 100644 index 00000000..65d162f4 --- /dev/null +++ b/hello_world/softnpu_provider/macro.control_table_miss.html @@ -0,0 +1,5 @@ +control_table_miss in hello_world::softnpu_provider - Rust +
macro_rules! control_table_miss {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_accepted!.html b/hello_world/softnpu_provider/macro.egress_accepted!.html new file mode 100644 index 00000000..bd4b37c4 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_accepted.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_accepted.html b/hello_world/softnpu_provider/macro.egress_accepted.html new file mode 100644 index 00000000..5cbab7b1 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_accepted.html @@ -0,0 +1,5 @@ +egress_accepted in hello_world::softnpu_provider - Rust +
macro_rules! egress_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_dropped!.html b/hello_world/softnpu_provider/macro.egress_dropped!.html new file mode 100644 index 00000000..3045dc36 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_dropped.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_dropped.html b/hello_world/softnpu_provider/macro.egress_dropped.html new file mode 100644 index 00000000..1354ba0c --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_dropped.html @@ -0,0 +1,5 @@ +egress_dropped in hello_world::softnpu_provider - Rust +
macro_rules! egress_dropped {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_table_hit!.html b/hello_world/softnpu_provider/macro.egress_table_hit!.html new file mode 100644 index 00000000..04b83478 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_table_hit!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_table_hit.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_table_hit.html b/hello_world/softnpu_provider/macro.egress_table_hit.html new file mode 100644 index 00000000..3380d908 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_table_hit.html @@ -0,0 +1,5 @@ +egress_table_hit in hello_world::softnpu_provider - Rust +
macro_rules! egress_table_hit {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_table_miss!.html b/hello_world/softnpu_provider/macro.egress_table_miss!.html new file mode 100644 index 00000000..686d6e77 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_table_miss!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_table_miss.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.egress_table_miss.html b/hello_world/softnpu_provider/macro.egress_table_miss.html new file mode 100644 index 00000000..2fbd41b8 --- /dev/null +++ b/hello_world/softnpu_provider/macro.egress_table_miss.html @@ -0,0 +1,5 @@ +egress_table_miss in hello_world::softnpu_provider - Rust +
macro_rules! egress_table_miss {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.ingress_accepted!.html b/hello_world/softnpu_provider/macro.ingress_accepted!.html new file mode 100644 index 00000000..0640a788 --- /dev/null +++ b/hello_world/softnpu_provider/macro.ingress_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.ingress_accepted.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.ingress_accepted.html b/hello_world/softnpu_provider/macro.ingress_accepted.html new file mode 100644 index 00000000..64f17617 --- /dev/null +++ b/hello_world/softnpu_provider/macro.ingress_accepted.html @@ -0,0 +1,5 @@ +ingress_accepted in hello_world::softnpu_provider - Rust +
macro_rules! ingress_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.ingress_dropped!.html b/hello_world/softnpu_provider/macro.ingress_dropped!.html new file mode 100644 index 00000000..e0505f61 --- /dev/null +++ b/hello_world/softnpu_provider/macro.ingress_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.ingress_dropped.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.ingress_dropped.html b/hello_world/softnpu_provider/macro.ingress_dropped.html new file mode 100644 index 00000000..33b578e8 --- /dev/null +++ b/hello_world/softnpu_provider/macro.ingress_dropped.html @@ -0,0 +1,5 @@ +ingress_dropped in hello_world::softnpu_provider - Rust +
macro_rules! ingress_dropped {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.parser_accepted!.html b/hello_world/softnpu_provider/macro.parser_accepted!.html new file mode 100644 index 00000000..cfa1b466 --- /dev/null +++ b/hello_world/softnpu_provider/macro.parser_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_accepted.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.parser_accepted.html b/hello_world/softnpu_provider/macro.parser_accepted.html new file mode 100644 index 00000000..132ddebb --- /dev/null +++ b/hello_world/softnpu_provider/macro.parser_accepted.html @@ -0,0 +1,5 @@ +parser_accepted in hello_world::softnpu_provider - Rust +
macro_rules! parser_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.parser_dropped!.html b/hello_world/softnpu_provider/macro.parser_dropped!.html new file mode 100644 index 00000000..de167747 --- /dev/null +++ b/hello_world/softnpu_provider/macro.parser_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_dropped.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.parser_dropped.html b/hello_world/softnpu_provider/macro.parser_dropped.html new file mode 100644 index 00000000..e246233a --- /dev/null +++ b/hello_world/softnpu_provider/macro.parser_dropped.html @@ -0,0 +1,6 @@ +parser_dropped in hello_world::softnpu_provider - Rust +
macro_rules! parser_dropped {
+    () => { ... };
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.parser_transition!.html b/hello_world/softnpu_provider/macro.parser_transition!.html new file mode 100644 index 00000000..605298f0 --- /dev/null +++ b/hello_world/softnpu_provider/macro.parser_transition!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_transition.html...

+ + + \ No newline at end of file diff --git a/hello_world/softnpu_provider/macro.parser_transition.html b/hello_world/softnpu_provider/macro.parser_transition.html new file mode 100644 index 00000000..656ec086 --- /dev/null +++ b/hello_world/softnpu_provider/macro.parser_transition.html @@ -0,0 +1,5 @@ +parser_transition in hello_world::softnpu_provider - Rust +
macro_rules! parser_transition {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/hello_world/softnpu_provider/sidebar-items.js b/hello_world/softnpu_provider/sidebar-items.js new file mode 100644 index 00000000..3e3f1355 --- /dev/null +++ b/hello_world/softnpu_provider/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"macro":["action","control_apply","control_table_hit","control_table_miss","egress_accepted","egress_dropped","egress_table_hit","egress_table_miss","ingress_accepted","ingress_dropped","parser_accepted","parser_dropped","parser_transition"]}; \ No newline at end of file diff --git a/hello_world/struct.egress_metadata_t.html b/hello_world/struct.egress_metadata_t.html new file mode 100644 index 00000000..e717f929 --- /dev/null +++ b/hello_world/struct.egress_metadata_t.html @@ -0,0 +1,97 @@ +egress_metadata_t in hello_world - Rust +
pub struct egress_metadata_t {
+    pub port: BitVec<u8, Msb0>,
+    pub drop: bool,
+    pub broadcast: bool,
+}

Fields§

§port: BitVec<u8, Msb0>§drop: bool§broadcast: bool

Implementations§

source§

impl egress_metadata_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for egress_metadata_t

source§

fn clone(&self) -> egress_metadata_t

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 Debug for egress_metadata_t

source§

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

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

impl Default for egress_metadata_t

source§

fn default() -> egress_metadata_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/hello_world/struct.ethernet_h.html b/hello_world/struct.ethernet_h.html new file mode 100644 index 00000000..94a31314 --- /dev/null +++ b/hello_world/struct.ethernet_h.html @@ -0,0 +1,98 @@ +ethernet_h in hello_world - Rust +

Struct hello_world::ethernet_h

source ·
pub struct ethernet_h {
+    pub valid: bool,
+    pub dst: BitVec<u8, Msb0>,
+    pub src: BitVec<u8, Msb0>,
+    pub ether_type: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§dst: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§ether_type: BitVec<u8, Msb0>

Implementations§

source§

impl ethernet_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ethernet_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ethernet_h

source§

fn clone(&self) -> ethernet_h

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 Debug for ethernet_h

source§

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

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

impl Default for ethernet_h

source§

fn default() -> ethernet_h

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

impl Header for ethernet_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/hello_world/struct.headers_t.html b/hello_world/struct.headers_t.html new file mode 100644 index 00000000..3bf0a425 --- /dev/null +++ b/hello_world/struct.headers_t.html @@ -0,0 +1,95 @@ +headers_t in hello_world - Rust +

Struct hello_world::headers_t

source ·
pub struct headers_t {
+    pub ethernet: ethernet_h,
+}

Fields§

§ethernet: ethernet_h

Implementations§

source§

impl headers_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for headers_t

source§

fn clone(&self) -> headers_t

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 Debug for headers_t

source§

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

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

impl Default for headers_t

source§

fn default() -> headers_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/hello_world/struct.ingress_metadata_t.html b/hello_world/struct.ingress_metadata_t.html new file mode 100644 index 00000000..4d806983 --- /dev/null +++ b/hello_world/struct.ingress_metadata_t.html @@ -0,0 +1,96 @@ +ingress_metadata_t in hello_world - Rust +
pub struct ingress_metadata_t {
+    pub port: BitVec<u8, Msb0>,
+    pub drop: bool,
+}

Fields§

§port: BitVec<u8, Msb0>§drop: bool

Implementations§

source§

impl ingress_metadata_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for ingress_metadata_t

source§

fn clone(&self) -> ingress_metadata_t

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 Debug for ingress_metadata_t

source§

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

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

impl Default for ingress_metadata_t

source§

fn default() -> ingress_metadata_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/hello_world/struct.main_pipeline.html b/hello_world/struct.main_pipeline.html new file mode 100644 index 00000000..f995be92 --- /dev/null +++ b/hello_world/struct.main_pipeline.html @@ -0,0 +1,121 @@ +main_pipeline in hello_world - Rust +
pub struct main_pipeline {
+    pub ingress_tbl: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>,
+    pub parse: fn(pkt: &mut packet_in<'_>, headers: &mut headers_t, ingress: &mut ingress_metadata_t) -> bool,
+    pub ingress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t, tbl: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>),
+    pub egress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t),
+    pub(crate) radix: u16,
+}

Fields§

§ingress_tbl: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>§parse: fn(pkt: &mut packet_in<'_>, headers: &mut headers_t, ingress: &mut ingress_metadata_t) -> bool§ingress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t, tbl: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>)§egress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t)§radix: u16

Implementations§

source§

impl main_pipeline

source

pub fn new(radix: u16) -> Self

source

pub(crate) fn process_packet_headers<'a>( + &mut self, + port: u16, + pkt: &mut packet_in<'a> +) -> Vec<(headers_t, u16)>

source

pub fn add_ingress_tbl_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_tbl_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_tbl_entries(&self) -> Vec<TableEntry>

Trait Implementations§

source§

impl Pipeline for main_pipeline

source§

fn process_packet<'a>( + &mut self, + port: u16, + pkt: &mut packet_in<'a> +) -> Vec<(packet_out<'a>, u16)>

Process an input packet and produce a set of output packets. Normally +there will be a single output packet. However, if the pipeline sets +egress_metadata_t.broadcast there may be multiple output packets.
source§

fn add_table_entry( + &mut self, + table_id: &str, + action_id: &str, + keyset_data: &[u8], + parameter_data: &[u8], + priority: u32 +)

Add an entry to a table identified by table_id.
source§

fn remove_table_entry(&mut self, table_id: &str, keyset_data: &[u8])

Remove an entry from a table identified by table_id.
source§

fn get_table_entries(&self, table_id: &str) -> Option<Vec<TableEntry>>

Get all the entries in a table.
source§

fn get_table_ids(&self) -> Vec<&str>

Get a list of table ids
source§

impl Send for main_pipeline

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/help.html b/help.html new file mode 100644 index 00000000..fbe1f8cf --- /dev/null +++ b/help.html @@ -0,0 +1,2 @@ +Help +

Rustdoc help

Back
\ No newline at end of file diff --git a/p4/all.html b/p4/all.html new file mode 100644 index 00000000..50b358da --- /dev/null +++ b/p4/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/p4/ast/enum.BinOp.html b/p4/ast/enum.BinOp.html new file mode 100644 index 00000000..dcb4ff33 --- /dev/null +++ b/p4/ast/enum.BinOp.html @@ -0,0 +1,29 @@ +BinOp in p4::ast - Rust +

Enum p4::ast::BinOp

source ·
pub enum BinOp {
+
Show 13 variants Add, + Subtract, + Mod, + Geq, + Gt, + Leq, + Lt, + Eq, + Mask, + NotEq, + BitAnd, + BitOr, + Xor, +
}

Variants§

§

Add

§

Subtract

§

Mod

§

Geq

§

Gt

§

Leq

§

Lt

§

Eq

§

Mask

§

NotEq

§

BitAnd

§

BitOr

§

Xor

Implementations§

source§

impl BinOp

source

pub fn english_verb(&self) -> &str

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for BinOp

source§

fn clone(&self) -> BinOp

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 Debug for BinOp

source§

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

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

impl PartialEq for BinOp

source§

fn eq(&self, other: &BinOp) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for BinOp

source§

impl Eq for BinOp

source§

impl StructuralPartialEq for BinOp

Auto Trait Implementations§

§

impl RefUnwindSafe for BinOp

§

impl Send for BinOp

§

impl Sync for BinOp

§

impl Unpin for BinOp

§

impl UnwindSafe for BinOp

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.DeclarationInfo.html b/p4/ast/enum.DeclarationInfo.html new file mode 100644 index 00000000..0c95e7d1 --- /dev/null +++ b/p4/ast/enum.DeclarationInfo.html @@ -0,0 +1,26 @@ +DeclarationInfo in p4::ast - Rust +

Enum p4::ast::DeclarationInfo

source ·
pub enum DeclarationInfo {
+    Parameter(Direction),
+    Method,
+    StructMember,
+    HeaderMember,
+    Local,
+    ControlTable,
+    ControlMember,
+    State,
+    Action,
+    ActionParameter(Direction),
+}

Variants§

§

Parameter(Direction)

§

Method

§

StructMember

§

HeaderMember

§

Local

§

ControlTable

§

ControlMember

§

State

§

Action

§

ActionParameter(Direction)

Trait Implementations§

source§

impl Clone for DeclarationInfo

source§

fn clone(&self) -> DeclarationInfo

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 Debug for DeclarationInfo

source§

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

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

impl PartialEq for DeclarationInfo

source§

fn eq(&self, other: &DeclarationInfo) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for DeclarationInfo

source§

impl StructuralPartialEq for DeclarationInfo

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.Direction.html b/p4/ast/enum.Direction.html new file mode 100644 index 00000000..3e4bfbbc --- /dev/null +++ b/p4/ast/enum.Direction.html @@ -0,0 +1,20 @@ +Direction in p4::ast - Rust +

Enum p4::ast::Direction

source ·
pub enum Direction {
+    In,
+    Out,
+    InOut,
+    Unspecified,
+}

Variants§

§

In

§

Out

§

InOut

§

Unspecified

Trait Implementations§

source§

impl Clone for Direction

source§

fn clone(&self) -> Direction

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 Debug for Direction

source§

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

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

impl PartialEq for Direction

source§

fn eq(&self, other: &Direction) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Direction

source§

impl Eq for Direction

source§

impl StructuralPartialEq for Direction

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.ExpressionKind.html b/p4/ast/enum.ExpressionKind.html new file mode 100644 index 00000000..5e494d60 --- /dev/null +++ b/p4/ast/enum.ExpressionKind.html @@ -0,0 +1,24 @@ +ExpressionKind in p4::ast - Rust +

Enum p4::ast::ExpressionKind

source ·
pub enum ExpressionKind {
+    BoolLit(bool),
+    IntegerLit(i128),
+    BitLit(u16, u128),
+    SignedLit(u16, i128),
+    Lvalue(Lvalue),
+    Binary(Box<Expression>, BinOp, Box<Expression>),
+    Index(Lvalue, Box<Expression>),
+    Slice(Box<Expression>, Box<Expression>),
+    Call(Call),
+    List(Vec<Box<Expression>>),
+}

Variants§

§

BoolLit(bool)

§

IntegerLit(i128)

§

BitLit(u16, u128)

§

SignedLit(u16, i128)

§

Lvalue(Lvalue)

§

Binary(Box<Expression>, BinOp, Box<Expression>)

§

Index(Lvalue, Box<Expression>)

§

Slice(Box<Expression>, Box<Expression>)

§

Call(Call)

§

List(Vec<Box<Expression>>)

Trait Implementations§

source§

impl Clone for ExpressionKind

source§

fn clone(&self) -> ExpressionKind

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 Debug for ExpressionKind

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.KeySetElementValue.html b/p4/ast/enum.KeySetElementValue.html new file mode 100644 index 00000000..2d7a01e9 --- /dev/null +++ b/p4/ast/enum.KeySetElementValue.html @@ -0,0 +1,19 @@ +KeySetElementValue in p4::ast - Rust +
pub enum KeySetElementValue {
+    Expression(Box<Expression>),
+    Default,
+    DontCare,
+    Masked(Box<Expression>, Box<Expression>),
+    Ranged(Box<Expression>, Box<Expression>),
+}

Variants§

§

Expression(Box<Expression>)

§

Default

§

DontCare

§

Masked(Box<Expression>, Box<Expression>)

§

Ranged(Box<Expression>, Box<Expression>)

Implementations§

source§

impl KeySetElementValue

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for KeySetElementValue

source§

fn clone(&self) -> KeySetElementValue

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 Debug for KeySetElementValue

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.MatchKind.html b/p4/ast/enum.MatchKind.html new file mode 100644 index 00000000..709d0a4b --- /dev/null +++ b/p4/ast/enum.MatchKind.html @@ -0,0 +1,18 @@ +MatchKind in p4::ast - Rust +

Enum p4::ast::MatchKind

source ·
pub enum MatchKind {
+    Exact,
+    Ternary,
+    LongestPrefixMatch,
+    Range,
+}

Variants§

§

Exact

§

Ternary

§

LongestPrefixMatch

§

Range

Implementations§

source§

impl MatchKind

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for MatchKind

source§

fn clone(&self) -> MatchKind

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 Debug for MatchKind

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.Statement.html b/p4/ast/enum.Statement.html new file mode 100644 index 00000000..c4294b8e --- /dev/null +++ b/p4/ast/enum.Statement.html @@ -0,0 +1,22 @@ +Statement in p4::ast - Rust +

Enum p4::ast::Statement

source ·
pub enum Statement {
+    Empty,
+    Assignment(Lvalue, Box<Expression>),
+    Call(Call),
+    If(IfBlock),
+    Variable(Variable),
+    Constant(Constant),
+    Transition(Transition),
+    Return(Option<Box<Expression>>),
+}

Variants§

§

Empty

§

Assignment(Lvalue, Box<Expression>)

§

Call(Call)

§

If(IfBlock)

§

Variable(Variable)

§

Constant(Constant)

§

Transition(Transition)

§

Return(Option<Box<Expression>>)

Implementations§

source§

impl Statement

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Statement

source§

fn clone(&self) -> Statement

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 Debug for Statement

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.Transition.html b/p4/ast/enum.Transition.html new file mode 100644 index 00000000..a8fab039 --- /dev/null +++ b/p4/ast/enum.Transition.html @@ -0,0 +1,16 @@ +Transition in p4::ast - Rust +

Enum p4::ast::Transition

source ·
pub enum Transition {
+    Reference(Lvalue),
+    Select(Select),
+}

Variants§

§

Reference(Lvalue)

§

Select(Select)

Implementations§

source§

impl Transition

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Transition

source§

fn clone(&self) -> Transition

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 Debug for Transition

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.Type.html b/p4/ast/enum.Type.html new file mode 100644 index 00000000..e824e64b --- /dev/null +++ b/p4/ast/enum.Type.html @@ -0,0 +1,31 @@ +Type in p4::ast - Rust +

Enum p4::ast::Type

source ·
pub enum Type {
+
Show 14 variants Bool, + Error, + Bit(usize), + Varbit(usize), + Int(usize), + String, + UserDefined(String), + ExternFunction, + Table, + Void, + List(Vec<Box<Type>>), + State, + Action, + HeaderMethod, +
}

Variants§

§

Bool

§

Error

§

Bit(usize)

§

Varbit(usize)

§

Int(usize)

§

String

§

UserDefined(String)

§

ExternFunction

§

Table

§

Void

§

List(Vec<Box<Type>>)

§

State

§

Action

§

HeaderMethod

Implementations§

source§

impl Type

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Type

source§

fn clone(&self) -> Type

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 Debug for Type

source§

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

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

impl Display for Type

source§

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

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

impl PartialEq for Type

source§

fn eq(&self, other: &Type) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Type

source§

impl StructuralPartialEq for Type

Auto Trait Implementations§

§

impl RefUnwindSafe for Type

§

impl Send for Type

§

impl Sync for Type

§

impl Unpin for Type

§

impl UnwindSafe for Type

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> 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,

§

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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/enum.UserDefinedType.html b/p4/ast/enum.UserDefinedType.html new file mode 100644 index 00000000..c98cbdd0 --- /dev/null +++ b/p4/ast/enum.UserDefinedType.html @@ -0,0 +1,16 @@ +UserDefinedType in p4::ast - Rust +

Enum p4::ast::UserDefinedType

source ·
pub enum UserDefinedType<'a> {
+    Struct(&'a Struct),
+    Header(&'a Header),
+    Extern(&'a Extern),
+}

Variants§

§

Struct(&'a Struct)

§

Header(&'a Header)

§

Extern(&'a Extern)

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for UserDefinedType<'a>

§

impl<'a> Send for UserDefinedType<'a>

§

impl<'a> Sync for UserDefinedType<'a>

§

impl<'a> Unpin for UserDefinedType<'a>

§

impl<'a> UnwindSafe for UserDefinedType<'a>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/index.html b/p4/ast/index.html new file mode 100644 index 00000000..5fcd33db --- /dev/null +++ b/p4/ast/index.html @@ -0,0 +1,2 @@ +p4::ast - Rust +
\ No newline at end of file diff --git a/p4/ast/sidebar-items.js b/p4/ast/sidebar-items.js new file mode 100644 index 00000000..3a5cc502 --- /dev/null +++ b/p4/ast/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["BinOp","DeclarationInfo","Direction","ExpressionKind","KeySetElementValue","MatchKind","Statement","Transition","Type","UserDefinedType"],"struct":["AST","Action","ActionParameter","ActionRef","Call","ConstTableEntry","Constant","Control","ControlParameter","ElseIfBlock","Expression","Extern","ExternMethod","Header","HeaderMember","IfBlock","KeySetElement","Lvalue","NameInfo","Package","PackageInstance","PackageParameter","Parser","Select","SelectElement","State","StatementBlock","Struct","StructMember","Table","Typedef","Variable"],"trait":["MutVisitor","MutVisitorMut","Visitor","VisitorMut"]}; \ No newline at end of file diff --git a/p4/ast/struct.AST.html b/p4/ast/struct.AST.html new file mode 100644 index 00000000..ac3b6fd1 --- /dev/null +++ b/p4/ast/struct.AST.html @@ -0,0 +1,22 @@ +AST in p4::ast - Rust +

Struct p4::ast::AST

source ·
pub struct AST {
+    pub constants: Vec<Constant>,
+    pub headers: Vec<Header>,
+    pub structs: Vec<Struct>,
+    pub typedefs: Vec<Typedef>,
+    pub controls: Vec<Control>,
+    pub parsers: Vec<Parser>,
+    pub packages: Vec<Package>,
+    pub package_instance: Option<PackageInstance>,
+    pub externs: Vec<Extern>,
+}

Fields§

§constants: Vec<Constant>§headers: Vec<Header>§structs: Vec<Struct>§typedefs: Vec<Typedef>§controls: Vec<Control>§parsers: Vec<Parser>§packages: Vec<Package>§package_instance: Option<PackageInstance>§externs: Vec<Extern>

Implementations§

source§

impl AST

source

pub fn get_struct(&self, name: &str) -> Option<&Struct>

source

pub fn get_header(&self, name: &str) -> Option<&Header>

source

pub fn get_extern(&self, name: &str) -> Option<&Extern>

source

pub fn get_control(&self, name: &str) -> Option<&Control>

source

pub fn get_parser(&self, name: &str) -> Option<&Parser>

source

pub fn get_user_defined_type(&self, name: &str) -> Option<UserDefinedType<'_>>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Debug for AST

source§

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

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

impl Default for AST

source§

fn default() -> AST

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

Auto Trait Implementations§

§

impl RefUnwindSafe for AST

§

impl Send for AST

§

impl Sync for AST

§

impl Unpin for AST

§

impl UnwindSafe for AST

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Action.html b/p4/ast/struct.Action.html new file mode 100644 index 00000000..823fa8db --- /dev/null +++ b/p4/ast/struct.Action.html @@ -0,0 +1,17 @@ +Action in p4::ast - Rust +

Struct p4::ast::Action

source ·
pub struct Action {
+    pub name: String,
+    pub parameters: Vec<ActionParameter>,
+    pub statement_block: StatementBlock,
+}

Fields§

§name: String§parameters: Vec<ActionParameter>§statement_block: StatementBlock

Implementations§

source§

impl Action

source

pub fn new(name: String) -> Self

source

pub fn names(&self) -> HashMap<String, NameInfo>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Action

source§

fn clone(&self) -> Action

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 Debug for Action

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.ActionParameter.html b/p4/ast/struct.ActionParameter.html new file mode 100644 index 00000000..29cb2173 --- /dev/null +++ b/p4/ast/struct.ActionParameter.html @@ -0,0 +1,19 @@ +ActionParameter in p4::ast - Rust +

Struct p4::ast::ActionParameter

source ·
pub struct ActionParameter {
+    pub direction: Direction,
+    pub ty: Type,
+    pub name: String,
+    pub ty_token: Token,
+    pub name_token: Token,
+}

Fields§

§direction: Direction§ty: Type§name: String§ty_token: Token§name_token: Token

Implementations§

source§

impl ActionParameter

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for ActionParameter

source§

fn clone(&self) -> ActionParameter

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 Debug for ActionParameter

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.ActionRef.html b/p4/ast/struct.ActionRef.html new file mode 100644 index 00000000..2207815c --- /dev/null +++ b/p4/ast/struct.ActionRef.html @@ -0,0 +1,17 @@ +ActionRef in p4::ast - Rust +

Struct p4::ast::ActionRef

source ·
pub struct ActionRef {
+    pub name: String,
+    pub parameters: Vec<Box<Expression>>,
+    pub token: Token,
+}

Fields§

§name: String§parameters: Vec<Box<Expression>>§token: Token

Implementations§

source§

impl ActionRef

source

pub fn new(name: String, token: Token) -> Self

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for ActionRef

source§

fn clone(&self) -> ActionRef

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 Debug for ActionRef

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Call.html b/p4/ast/struct.Call.html new file mode 100644 index 00000000..93f5da25 --- /dev/null +++ b/p4/ast/struct.Call.html @@ -0,0 +1,17 @@ +Call in p4::ast - Rust +

Struct p4::ast::Call

source ·
pub struct Call {
+    pub lval: Lvalue,
+    pub args: Vec<Box<Expression>>,
+}
Expand description

A function or method call

+

Fields§

§lval: Lvalue§args: Vec<Box<Expression>>

Implementations§

source§

impl Call

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Call

source§

fn clone(&self) -> Call

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 Debug for Call

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl RefUnwindSafe for Call

§

impl Send for Call

§

impl Sync for Call

§

impl Unpin for Call

§

impl UnwindSafe for Call

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.ConstTableEntry.html b/p4/ast/struct.ConstTableEntry.html new file mode 100644 index 00000000..7df71b32 --- /dev/null +++ b/p4/ast/struct.ConstTableEntry.html @@ -0,0 +1,16 @@ +ConstTableEntry in p4::ast - Rust +

Struct p4::ast::ConstTableEntry

source ·
pub struct ConstTableEntry {
+    pub keyset: Vec<KeySetElement>,
+    pub action: ActionRef,
+}

Fields§

§keyset: Vec<KeySetElement>§action: ActionRef

Implementations§

source§

impl ConstTableEntry

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for ConstTableEntry

source§

fn clone(&self) -> ConstTableEntry

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 Debug for ConstTableEntry

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Constant.html b/p4/ast/struct.Constant.html new file mode 100644 index 00000000..4ed054c0 --- /dev/null +++ b/p4/ast/struct.Constant.html @@ -0,0 +1,17 @@ +Constant in p4::ast - Rust +

Struct p4::ast::Constant

source ·
pub struct Constant {
+    pub ty: Type,
+    pub name: String,
+    pub initializer: Box<Expression>,
+}

Fields§

§ty: Type§name: String§initializer: Box<Expression>

Implementations§

source§

impl Constant

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Constant

source§

fn clone(&self) -> Constant

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 Debug for Constant

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Control.html b/p4/ast/struct.Control.html new file mode 100644 index 00000000..9e70acb6 --- /dev/null +++ b/p4/ast/struct.Control.html @@ -0,0 +1,31 @@ +Control in p4::ast - Rust +

Struct p4::ast::Control

source ·
pub struct Control {
+    pub name: String,
+    pub variables: Vec<Variable>,
+    pub constants: Vec<Constant>,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<ControlParameter>,
+    pub actions: Vec<Action>,
+    pub tables: Vec<Table>,
+    pub apply: StatementBlock,
+}

Fields§

§name: String§variables: Vec<Variable>§constants: Vec<Constant>§type_parameters: Vec<String>§parameters: Vec<ControlParameter>§actions: Vec<Action>§tables: Vec<Table>§apply: StatementBlock

Implementations§

source§

impl Control

source

pub fn new(name: String) -> Self

source

pub fn get_parameter(&self, name: &str) -> Option<&ControlParameter>

source

pub fn get_action(&self, name: &str) -> Option<&Action>

source

pub fn get_table(&self, name: &str) -> Option<&Table>

source

pub fn tables<'a>( + &'a self, + ast: &'a AST +) -> Vec<(Vec<(String, &Control)>, &Table)>

Return all the tables in this control block, recursively expanding local +control block variables and including their tables. In the returned +vector, the table in the second element of the tuple belongs to the +control in the first element.

+
source

pub fn is_type_parameter(&self, name: &str) -> bool

source

pub fn names(&self) -> HashMap<String, NameInfo>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Control

source§

fn clone(&self) -> Control

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 Debug for Control

source§

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

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

impl PartialEq for Control

source§

fn eq(&self, other: &Control) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.ControlParameter.html b/p4/ast/struct.ControlParameter.html new file mode 100644 index 00000000..02b608a4 --- /dev/null +++ b/p4/ast/struct.ControlParameter.html @@ -0,0 +1,20 @@ +ControlParameter in p4::ast - Rust +

Struct p4::ast::ControlParameter

source ·
pub struct ControlParameter {
+    pub direction: Direction,
+    pub ty: Type,
+    pub name: String,
+    pub dir_token: Token,
+    pub ty_token: Token,
+    pub name_token: Token,
+}

Fields§

§direction: Direction§ty: Type§name: String§dir_token: Token§ty_token: Token§name_token: Token

Implementations§

source§

impl ControlParameter

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for ControlParameter

source§

fn clone(&self) -> ControlParameter

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 Debug for ControlParameter

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.ElseIfBlock.html b/p4/ast/struct.ElseIfBlock.html new file mode 100644 index 00000000..6f742186 --- /dev/null +++ b/p4/ast/struct.ElseIfBlock.html @@ -0,0 +1,16 @@ +ElseIfBlock in p4::ast - Rust +

Struct p4::ast::ElseIfBlock

source ·
pub struct ElseIfBlock {
+    pub predicate: Box<Expression>,
+    pub block: StatementBlock,
+}

Fields§

§predicate: Box<Expression>§block: StatementBlock

Implementations§

source§

impl ElseIfBlock

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for ElseIfBlock

source§

fn clone(&self) -> ElseIfBlock

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 Debug for ElseIfBlock

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Expression.html b/p4/ast/struct.Expression.html new file mode 100644 index 00000000..3d0a1038 --- /dev/null +++ b/p4/ast/struct.Expression.html @@ -0,0 +1,20 @@ +Expression in p4::ast - Rust +

Struct p4::ast::Expression

source ·
pub struct Expression {
+    pub token: Token,
+    pub kind: ExpressionKind,
+}

Fields§

§token: Token§kind: ExpressionKind

Implementations§

source§

impl Expression

source

pub fn new(token: Token, kind: ExpressionKind) -> Box<Self>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Expression

source§

fn clone(&self) -> Expression

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 Debug for Expression

source§

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

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

impl Hash for Expression

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Expression

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Expression

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Extern.html b/p4/ast/struct.Extern.html new file mode 100644 index 00000000..c5ac98da --- /dev/null +++ b/p4/ast/struct.Extern.html @@ -0,0 +1,17 @@ +Extern in p4::ast - Rust +

Struct p4::ast::Extern

source ·
pub struct Extern {
+    pub name: String,
+    pub methods: Vec<ExternMethod>,
+    pub token: Token,
+}

Fields§

§name: String§methods: Vec<ExternMethod>§token: Token

Implementations§

source§

impl Extern

source

pub fn names(&self) -> HashMap<String, NameInfo>

source

pub fn get_method(&self, name: &str) -> Option<&ExternMethod>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Extern

source§

fn clone(&self) -> Extern

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 Debug for Extern

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.ExternMethod.html b/p4/ast/struct.ExternMethod.html new file mode 100644 index 00000000..76d5ba32 --- /dev/null +++ b/p4/ast/struct.ExternMethod.html @@ -0,0 +1,18 @@ +ExternMethod in p4::ast - Rust +

Struct p4::ast::ExternMethod

source ·
pub struct ExternMethod {
+    pub return_type: Type,
+    pub name: String,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<ControlParameter>,
+}

Fields§

§return_type: Type§name: String§type_parameters: Vec<String>§parameters: Vec<ControlParameter>

Implementations§

source§

impl ExternMethod

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for ExternMethod

source§

fn clone(&self) -> ExternMethod

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 Debug for ExternMethod

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Header.html b/p4/ast/struct.Header.html new file mode 100644 index 00000000..8a3446fe --- /dev/null +++ b/p4/ast/struct.Header.html @@ -0,0 +1,16 @@ +Header in p4::ast - Rust +

Struct p4::ast::Header

source ·
pub struct Header {
+    pub name: String,
+    pub members: Vec<HeaderMember>,
+}

Fields§

§name: String§members: Vec<HeaderMember>

Implementations§

source§

impl Header

source

pub fn new(name: String) -> Self

source

pub fn names(&self) -> HashMap<String, NameInfo>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Header

source§

fn clone(&self) -> Header

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 Debug for Header

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.HeaderMember.html b/p4/ast/struct.HeaderMember.html new file mode 100644 index 00000000..34103999 --- /dev/null +++ b/p4/ast/struct.HeaderMember.html @@ -0,0 +1,17 @@ +HeaderMember in p4::ast - Rust +

Struct p4::ast::HeaderMember

source ·
pub struct HeaderMember {
+    pub ty: Type,
+    pub name: String,
+    pub token: Token,
+}

Fields§

§ty: Type§name: String§token: Token

Implementations§

source§

impl HeaderMember

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for HeaderMember

source§

fn clone(&self) -> HeaderMember

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 Debug for HeaderMember

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.IfBlock.html b/p4/ast/struct.IfBlock.html new file mode 100644 index 00000000..4f3a250f --- /dev/null +++ b/p4/ast/struct.IfBlock.html @@ -0,0 +1,18 @@ +IfBlock in p4::ast - Rust +

Struct p4::ast::IfBlock

source ·
pub struct IfBlock {
+    pub predicate: Box<Expression>,
+    pub block: StatementBlock,
+    pub else_ifs: Vec<ElseIfBlock>,
+    pub else_block: Option<StatementBlock>,
+}

Fields§

§predicate: Box<Expression>§block: StatementBlock§else_ifs: Vec<ElseIfBlock>§else_block: Option<StatementBlock>

Implementations§

source§

impl IfBlock

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for IfBlock

source§

fn clone(&self) -> IfBlock

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 Debug for IfBlock

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.KeySetElement.html b/p4/ast/struct.KeySetElement.html new file mode 100644 index 00000000..5dfa4bf4 --- /dev/null +++ b/p4/ast/struct.KeySetElement.html @@ -0,0 +1,16 @@ +KeySetElement in p4::ast - Rust +

Struct p4::ast::KeySetElement

source ·
pub struct KeySetElement {
+    pub value: KeySetElementValue,
+    pub token: Token,
+}

Fields§

§value: KeySetElementValue§token: Token

Implementations§

source§

impl KeySetElement

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for KeySetElement

source§

fn clone(&self) -> KeySetElement

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 Debug for KeySetElement

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Lvalue.html b/p4/ast/struct.Lvalue.html new file mode 100644 index 00000000..80ca451e --- /dev/null +++ b/p4/ast/struct.Lvalue.html @@ -0,0 +1,25 @@ +Lvalue in p4::ast - Rust +

Struct p4::ast::Lvalue

source ·
pub struct Lvalue {
+    pub name: String,
+    pub token: Token,
+}

Fields§

§name: String§token: Token

Implementations§

source§

impl Lvalue

source

pub fn parts(&self) -> Vec<&str>

source

pub fn root(&self) -> &str

source

pub fn leaf(&self) -> &str

source

pub fn degree(&self) -> usize

source

pub fn pop_left(&self) -> Self

source

pub fn pop_right(&self) -> Self

Trait Implementations§

source§

impl Clone for Lvalue

source§

fn clone(&self) -> Lvalue

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 Debug for Lvalue

source§

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

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

impl Hash for Lvalue

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl Ord for Lvalue

source§

fn cmp(&self, other: &Self) -> Ordering

This method returns an Ordering between self and other. Read more
1.21.0 · source§

fn max(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the maximum of two values. Read more
1.21.0 · source§

fn min(self, other: Self) -> Self
where + Self: Sized,

Compares and returns the minimum of two values. Read more
1.50.0 · source§

fn clamp(self, min: Self, max: Self) -> Self
where + Self: Sized + PartialOrd,

Restrict a value to a certain interval. Read more
source§

impl PartialEq for Lvalue

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl PartialOrd for Lvalue

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

This method returns an ordering between self and other values if one exists. Read more
1.0.0 · source§

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

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

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

This method tests less than or equal to (for self and other) and is used by the <= +operator. Read more
1.0.0 · source§

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

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

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

This method tests greater than or equal to (for self and other) and is used by the >= +operator. Read more
source§

impl Eq for Lvalue

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.NameInfo.html b/p4/ast/struct.NameInfo.html new file mode 100644 index 00000000..e133d815 --- /dev/null +++ b/p4/ast/struct.NameInfo.html @@ -0,0 +1,16 @@ +NameInfo in p4::ast - Rust +

Struct p4::ast::NameInfo

source ·
pub struct NameInfo {
+    pub ty: Type,
+    pub decl: DeclarationInfo,
+}

Fields§

§ty: Type§decl: DeclarationInfo

Trait Implementations§

source§

impl Clone for NameInfo

source§

fn clone(&self) -> NameInfo

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 Debug for NameInfo

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Package.html b/p4/ast/struct.Package.html new file mode 100644 index 00000000..ea668ec7 --- /dev/null +++ b/p4/ast/struct.Package.html @@ -0,0 +1,16 @@ +Package in p4::ast - Rust +

Struct p4::ast::Package

source ·
pub struct Package {
+    pub name: String,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<PackageParameter>,
+}

Fields§

§name: String§type_parameters: Vec<String>§parameters: Vec<PackageParameter>

Implementations§

source§

impl Package

source

pub fn new(name: String) -> Self

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Debug for Package

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.PackageInstance.html b/p4/ast/struct.PackageInstance.html new file mode 100644 index 00000000..268c413e --- /dev/null +++ b/p4/ast/struct.PackageInstance.html @@ -0,0 +1,16 @@ +PackageInstance in p4::ast - Rust +

Struct p4::ast::PackageInstance

source ·
pub struct PackageInstance {
+    pub instance_type: String,
+    pub name: String,
+    pub parameters: Vec<String>,
+}

Fields§

§instance_type: String§name: String§parameters: Vec<String>

Implementations§

source§

impl PackageInstance

source

pub fn new(instance_type: String) -> Self

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Debug for PackageInstance

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.PackageParameter.html b/p4/ast/struct.PackageParameter.html new file mode 100644 index 00000000..f4e9a7b4 --- /dev/null +++ b/p4/ast/struct.PackageParameter.html @@ -0,0 +1,16 @@ +PackageParameter in p4::ast - Rust +

Struct p4::ast::PackageParameter

source ·
pub struct PackageParameter {
+    pub type_name: String,
+    pub type_parameters: Vec<String>,
+    pub name: String,
+}

Fields§

§type_name: String§type_parameters: Vec<String>§name: String

Implementations§

source§

impl PackageParameter

source

pub fn new(type_name: String) -> Self

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Debug for PackageParameter

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Parser.html b/p4/ast/struct.Parser.html new file mode 100644 index 00000000..e13bbb27 --- /dev/null +++ b/p4/ast/struct.Parser.html @@ -0,0 +1,21 @@ +Parser in p4::ast - Rust +

Struct p4::ast::Parser

source ·
pub struct Parser {
+    pub name: String,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<ControlParameter>,
+    pub states: Vec<State>,
+    pub decl_only: bool,
+    pub token: Token,
+}

Fields§

§name: String§type_parameters: Vec<String>§parameters: Vec<ControlParameter>§states: Vec<State>§decl_only: bool§token: Token

The first token of this parser, used for error reporting.

+

Implementations§

source§

impl Parser

source

pub fn new(name: String, token: Token) -> Self

source

pub fn is_type_parameter(&self, name: &str) -> bool

source

pub fn names(&self) -> HashMap<String, NameInfo>

source

pub fn get_start_state(&self) -> Option<&State>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Parser

source§

fn clone(&self) -> Parser

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 Debug for Parser

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Select.html b/p4/ast/struct.Select.html new file mode 100644 index 00000000..7a4f4f3b --- /dev/null +++ b/p4/ast/struct.Select.html @@ -0,0 +1,16 @@ +Select in p4::ast - Rust +

Struct p4::ast::Select

source ·
pub struct Select {
+    pub parameters: Vec<Box<Expression>>,
+    pub elements: Vec<SelectElement>,
+}

Fields§

§parameters: Vec<Box<Expression>>§elements: Vec<SelectElement>

Implementations§

source§

impl Select

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Select

source§

fn clone(&self) -> Select

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 Debug for Select

source§

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

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

impl Default for Select

source§

fn default() -> Select

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

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.SelectElement.html b/p4/ast/struct.SelectElement.html new file mode 100644 index 00000000..1926fe77 --- /dev/null +++ b/p4/ast/struct.SelectElement.html @@ -0,0 +1,16 @@ +SelectElement in p4::ast - Rust +

Struct p4::ast::SelectElement

source ·
pub struct SelectElement {
+    pub keyset: Vec<KeySetElement>,
+    pub name: String,
+}

Fields§

§keyset: Vec<KeySetElement>§name: String

Implementations§

source§

impl SelectElement

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for SelectElement

source§

fn clone(&self) -> SelectElement

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 Debug for SelectElement

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.State.html b/p4/ast/struct.State.html new file mode 100644 index 00000000..236696b4 --- /dev/null +++ b/p4/ast/struct.State.html @@ -0,0 +1,17 @@ +State in p4::ast - Rust +

Struct p4::ast::State

source ·
pub struct State {
+    pub name: String,
+    pub statements: StatementBlock,
+    pub token: Token,
+}

Fields§

§name: String§statements: StatementBlock§token: Token

Implementations§

source§

impl State

source

pub fn new(name: String, token: Token) -> Self

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for State

source§

fn clone(&self) -> State

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 Debug for State

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl RefUnwindSafe for State

§

impl Send for State

§

impl Sync for State

§

impl Unpin for State

§

impl UnwindSafe for State

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.StatementBlock.html b/p4/ast/struct.StatementBlock.html new file mode 100644 index 00000000..55bc320c --- /dev/null +++ b/p4/ast/struct.StatementBlock.html @@ -0,0 +1,15 @@ +StatementBlock in p4::ast - Rust +

Struct p4::ast::StatementBlock

source ·
pub struct StatementBlock {
+    pub statements: Vec<Statement>,
+}

Fields§

§statements: Vec<Statement>

Trait Implementations§

source§

impl Clone for StatementBlock

source§

fn clone(&self) -> StatementBlock

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 Debug for StatementBlock

source§

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

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

impl Default for StatementBlock

source§

fn default() -> StatementBlock

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

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Struct.html b/p4/ast/struct.Struct.html new file mode 100644 index 00000000..3ed5b673 --- /dev/null +++ b/p4/ast/struct.Struct.html @@ -0,0 +1,16 @@ +Struct in p4::ast - Rust +

Struct p4::ast::Struct

source ·
pub struct Struct {
+    pub name: String,
+    pub members: Vec<StructMember>,
+}

Fields§

§name: String§members: Vec<StructMember>

Implementations§

source§

impl Struct

source

pub fn new(name: String) -> Self

source

pub fn names(&self) -> HashMap<String, NameInfo>

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Struct

source§

fn clone(&self) -> Struct

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 Debug for Struct

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.StructMember.html b/p4/ast/struct.StructMember.html new file mode 100644 index 00000000..7616edaf --- /dev/null +++ b/p4/ast/struct.StructMember.html @@ -0,0 +1,17 @@ +StructMember in p4::ast - Rust +

Struct p4::ast::StructMember

source ·
pub struct StructMember {
+    pub ty: Type,
+    pub name: String,
+    pub token: Token,
+}

Fields§

§ty: Type§name: String§token: Token

Implementations§

source§

impl StructMember

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for StructMember

source§

fn clone(&self) -> StructMember

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 Debug for StructMember

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Table.html b/p4/ast/struct.Table.html new file mode 100644 index 00000000..cf1a5fe6 --- /dev/null +++ b/p4/ast/struct.Table.html @@ -0,0 +1,21 @@ +Table in p4::ast - Rust +

Struct p4::ast::Table

source ·
pub struct Table {
+    pub name: String,
+    pub actions: Vec<Lvalue>,
+    pub default_action: String,
+    pub key: Vec<(Lvalue, MatchKind)>,
+    pub const_entries: Vec<ConstTableEntry>,
+    pub size: usize,
+    pub token: Token,
+}

Fields§

§name: String§actions: Vec<Lvalue>§default_action: String§key: Vec<(Lvalue, MatchKind)>§const_entries: Vec<ConstTableEntry>§size: usize§token: Token

Implementations§

source§

impl Table

source

pub fn new(name: String, token: Token) -> Self

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Table

source§

fn clone(&self) -> Table

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 Debug for Table

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl RefUnwindSafe for Table

§

impl Send for Table

§

impl Sync for Table

§

impl Unpin for Table

§

impl UnwindSafe for Table

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Typedef.html b/p4/ast/struct.Typedef.html new file mode 100644 index 00000000..f33474df --- /dev/null +++ b/p4/ast/struct.Typedef.html @@ -0,0 +1,16 @@ +Typedef in p4::ast - Rust +

Struct p4::ast::Typedef

source ·
pub struct Typedef {
+    pub ty: Type,
+    pub name: String,
+}

Fields§

§ty: Type§name: String

Implementations§

source§

impl Typedef

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Typedef

source§

fn clone(&self) -> Typedef

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 Debug for Typedef

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/struct.Variable.html b/p4/ast/struct.Variable.html new file mode 100644 index 00000000..f48c6c55 --- /dev/null +++ b/p4/ast/struct.Variable.html @@ -0,0 +1,19 @@ +Variable in p4::ast - Rust +

Struct p4::ast::Variable

source ·
pub struct Variable {
+    pub ty: Type,
+    pub name: String,
+    pub initializer: Option<Box<Expression>>,
+    pub parameters: Vec<ControlParameter>,
+    pub token: Token,
+}

Fields§

§ty: Type§name: String§initializer: Option<Box<Expression>>§parameters: Vec<ControlParameter>§token: Token

Implementations§

source§

impl Variable

source

pub fn accept<V: Visitor>(&self, v: &V)

source

pub fn accept_mut<V: VisitorMut>(&self, v: &mut V)

source

pub fn mut_accept<V: MutVisitor>(&mut self, v: &V)

source

pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V)

Trait Implementations§

source§

impl Clone for Variable

source§

fn clone(&self) -> Variable

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 Debug for Variable

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/ast/trait.MutVisitor.html b/p4/ast/trait.MutVisitor.html new file mode 100644 index 00000000..e893203e --- /dev/null +++ b/p4/ast/trait.MutVisitor.html @@ -0,0 +1,39 @@ +MutVisitor in p4::ast - Rust +

Trait p4::ast::MutVisitor

source ·
pub trait MutVisitor {
+
Show 35 methods // Provided methods + fn constant(&self, _: &mut Constant) { ... } + fn header(&self, _: &mut Header) { ... } + fn p4struct(&self, _: &mut Struct) { ... } + fn typedef(&self, _: &mut Typedef) { ... } + fn control(&self, _: &mut Control) { ... } + fn parser(&self, _: &mut Parser) { ... } + fn package(&self, _: &mut Package) { ... } + fn package_instance(&self, _: &mut PackageInstance) { ... } + fn p4extern(&self, _: &mut Extern) { ... } + fn statement(&self, _: &mut Statement) { ... } + fn action(&self, _: &mut Action) { ... } + fn control_parameter(&self, _: &mut ControlParameter) { ... } + fn action_parameter(&self, _: &mut ActionParameter) { ... } + fn expression(&self, _: &mut Expression) { ... } + fn header_member(&self, _: &mut HeaderMember) { ... } + fn struct_member(&self, _: &mut StructMember) { ... } + fn call(&self, _: &mut Call) { ... } + fn typ(&self, _: &mut Type) { ... } + fn binop(&self, _: &mut BinOp) { ... } + fn lvalue(&self, _: &mut Lvalue) { ... } + fn variable(&self, _: &mut Variable) { ... } + fn if_block(&self, _: &mut IfBlock) { ... } + fn else_if_block(&self, _: &mut ElseIfBlock) { ... } + fn transition(&self, _: &mut Transition) { ... } + fn select(&self, _: &mut Select) { ... } + fn select_element(&self, _: &mut SelectElement) { ... } + fn key_set_element(&self, _: &mut KeySetElement) { ... } + fn key_set_element_value(&self, _: &mut KeySetElementValue) { ... } + fn table(&self, _: &mut Table) { ... } + fn match_kind(&self, _: &mut MatchKind) { ... } + fn const_table_entry(&self, _: &mut ConstTableEntry) { ... } + fn action_ref(&self, _: &mut ActionRef) { ... } + fn state(&self, _: &mut State) { ... } + fn package_parameter(&self, _: &mut PackageParameter) { ... } + fn extern_method(&self, _: &mut ExternMethod) { ... } +
}

Provided Methods§

source

fn constant(&self, _: &mut Constant)

source

fn header(&self, _: &mut Header)

source

fn p4struct(&self, _: &mut Struct)

source

fn typedef(&self, _: &mut Typedef)

source

fn control(&self, _: &mut Control)

source

fn parser(&self, _: &mut Parser)

source

fn package(&self, _: &mut Package)

source

fn package_instance(&self, _: &mut PackageInstance)

source

fn p4extern(&self, _: &mut Extern)

source

fn statement(&self, _: &mut Statement)

source

fn action(&self, _: &mut Action)

source

fn control_parameter(&self, _: &mut ControlParameter)

source

fn action_parameter(&self, _: &mut ActionParameter)

source

fn expression(&self, _: &mut Expression)

source

fn header_member(&self, _: &mut HeaderMember)

source

fn struct_member(&self, _: &mut StructMember)

source

fn call(&self, _: &mut Call)

source

fn typ(&self, _: &mut Type)

source

fn binop(&self, _: &mut BinOp)

source

fn lvalue(&self, _: &mut Lvalue)

source

fn variable(&self, _: &mut Variable)

source

fn if_block(&self, _: &mut IfBlock)

source

fn else_if_block(&self, _: &mut ElseIfBlock)

source

fn transition(&self, _: &mut Transition)

source

fn select(&self, _: &mut Select)

source

fn select_element(&self, _: &mut SelectElement)

source

fn key_set_element(&self, _: &mut KeySetElement)

source

fn key_set_element_value(&self, _: &mut KeySetElementValue)

source

fn table(&self, _: &mut Table)

source

fn match_kind(&self, _: &mut MatchKind)

source

fn const_table_entry(&self, _: &mut ConstTableEntry)

source

fn action_ref(&self, _: &mut ActionRef)

source

fn state(&self, _: &mut State)

source

fn package_parameter(&self, _: &mut PackageParameter)

source

fn extern_method(&self, _: &mut ExternMethod)

Implementors§

\ No newline at end of file diff --git a/p4/ast/trait.MutVisitorMut.html b/p4/ast/trait.MutVisitorMut.html new file mode 100644 index 00000000..987e38a1 --- /dev/null +++ b/p4/ast/trait.MutVisitorMut.html @@ -0,0 +1,39 @@ +MutVisitorMut in p4::ast - Rust +

Trait p4::ast::MutVisitorMut

source ·
pub trait MutVisitorMut {
+
Show 35 methods // Provided methods + fn constant(&mut self, _: &mut Constant) { ... } + fn header(&mut self, _: &mut Header) { ... } + fn p4struct(&mut self, _: &mut Struct) { ... } + fn typedef(&mut self, _: &mut Typedef) { ... } + fn control(&mut self, _: &mut Control) { ... } + fn parser(&mut self, _: &mut Parser) { ... } + fn package(&mut self, _: &mut Package) { ... } + fn package_instance(&mut self, _: &mut PackageInstance) { ... } + fn p4extern(&mut self, _: &mut Extern) { ... } + fn statement(&mut self, _: &mut Statement) { ... } + fn action(&mut self, _: &mut Action) { ... } + fn control_parameter(&mut self, _: &mut ControlParameter) { ... } + fn action_parameter(&mut self, _: &mut ActionParameter) { ... } + fn expression(&mut self, _: &mut Expression) { ... } + fn header_member(&mut self, _: &mut HeaderMember) { ... } + fn struct_member(&mut self, _: &mut StructMember) { ... } + fn call(&mut self, _: &mut Call) { ... } + fn typ(&mut self, _: &mut Type) { ... } + fn binop(&mut self, _: &mut BinOp) { ... } + fn lvalue(&mut self, _: &mut Lvalue) { ... } + fn variable(&mut self, _: &mut Variable) { ... } + fn if_block(&mut self, _: &mut IfBlock) { ... } + fn else_if_block(&mut self, _: &mut ElseIfBlock) { ... } + fn transition(&mut self, _: &mut Transition) { ... } + fn select(&mut self, _: &mut Select) { ... } + fn select_element(&mut self, _: &mut SelectElement) { ... } + fn key_set_element(&mut self, _: &mut KeySetElement) { ... } + fn key_set_element_value(&mut self, _: &mut KeySetElementValue) { ... } + fn table(&mut self, _: &mut Table) { ... } + fn match_kind(&mut self, _: &mut MatchKind) { ... } + fn const_table_entry(&mut self, _: &mut ConstTableEntry) { ... } + fn action_ref(&mut self, _: &mut ActionRef) { ... } + fn state(&mut self, _: &mut State) { ... } + fn package_parameter(&mut self, _: &mut PackageParameter) { ... } + fn extern_method(&mut self, _: &mut ExternMethod) { ... } +
}

Provided Methods§

source

fn constant(&mut self, _: &mut Constant)

source

fn header(&mut self, _: &mut Header)

source

fn p4struct(&mut self, _: &mut Struct)

source

fn typedef(&mut self, _: &mut Typedef)

source

fn control(&mut self, _: &mut Control)

source

fn parser(&mut self, _: &mut Parser)

source

fn package(&mut self, _: &mut Package)

source

fn package_instance(&mut self, _: &mut PackageInstance)

source

fn p4extern(&mut self, _: &mut Extern)

source

fn statement(&mut self, _: &mut Statement)

source

fn action(&mut self, _: &mut Action)

source

fn control_parameter(&mut self, _: &mut ControlParameter)

source

fn action_parameter(&mut self, _: &mut ActionParameter)

source

fn expression(&mut self, _: &mut Expression)

source

fn header_member(&mut self, _: &mut HeaderMember)

source

fn struct_member(&mut self, _: &mut StructMember)

source

fn call(&mut self, _: &mut Call)

source

fn typ(&mut self, _: &mut Type)

source

fn binop(&mut self, _: &mut BinOp)

source

fn lvalue(&mut self, _: &mut Lvalue)

source

fn variable(&mut self, _: &mut Variable)

source

fn if_block(&mut self, _: &mut IfBlock)

source

fn else_if_block(&mut self, _: &mut ElseIfBlock)

source

fn transition(&mut self, _: &mut Transition)

source

fn select(&mut self, _: &mut Select)

source

fn select_element(&mut self, _: &mut SelectElement)

source

fn key_set_element(&mut self, _: &mut KeySetElement)

source

fn key_set_element_value(&mut self, _: &mut KeySetElementValue)

source

fn table(&mut self, _: &mut Table)

source

fn match_kind(&mut self, _: &mut MatchKind)

source

fn const_table_entry(&mut self, _: &mut ConstTableEntry)

source

fn action_ref(&mut self, _: &mut ActionRef)

source

fn state(&mut self, _: &mut State)

source

fn package_parameter(&mut self, _: &mut PackageParameter)

source

fn extern_method(&mut self, _: &mut ExternMethod)

Implementors§

\ No newline at end of file diff --git a/p4/ast/trait.Visitor.html b/p4/ast/trait.Visitor.html new file mode 100644 index 00000000..5d4fa05a --- /dev/null +++ b/p4/ast/trait.Visitor.html @@ -0,0 +1,39 @@ +Visitor in p4::ast - Rust +

Trait p4::ast::Visitor

source ·
pub trait Visitor {
+
Show 35 methods // Provided methods + fn constant(&self, _: &Constant) { ... } + fn header(&self, _: &Header) { ... } + fn p4struct(&self, _: &Struct) { ... } + fn typedef(&self, _: &Typedef) { ... } + fn control(&self, _: &Control) { ... } + fn parser(&self, _: &Parser) { ... } + fn package(&self, _: &Package) { ... } + fn package_instance(&self, _: &PackageInstance) { ... } + fn p4extern(&self, _: &Extern) { ... } + fn statement(&self, _: &Statement) { ... } + fn action(&self, _: &Action) { ... } + fn control_parameter(&self, _: &ControlParameter) { ... } + fn action_parameter(&self, _: &ActionParameter) { ... } + fn expression(&self, _: &Expression) { ... } + fn header_member(&self, _: &HeaderMember) { ... } + fn struct_member(&self, _: &StructMember) { ... } + fn call(&self, _: &Call) { ... } + fn typ(&self, _: &Type) { ... } + fn binop(&self, _: &BinOp) { ... } + fn lvalue(&self, _: &Lvalue) { ... } + fn variable(&self, _: &Variable) { ... } + fn if_block(&self, _: &IfBlock) { ... } + fn else_if_block(&self, _: &ElseIfBlock) { ... } + fn transition(&self, _: &Transition) { ... } + fn select(&self, _: &Select) { ... } + fn select_element(&self, _: &SelectElement) { ... } + fn key_set_element(&self, _: &KeySetElement) { ... } + fn key_set_element_value(&self, _: &KeySetElementValue) { ... } + fn table(&self, _: &Table) { ... } + fn match_kind(&self, _: &MatchKind) { ... } + fn const_table_entry(&self, _: &ConstTableEntry) { ... } + fn action_ref(&self, _: &ActionRef) { ... } + fn state(&self, _: &State) { ... } + fn package_parameter(&self, _: &PackageParameter) { ... } + fn extern_method(&self, _: &ExternMethod) { ... } +
}

Provided Methods§

Implementors§

\ No newline at end of file diff --git a/p4/ast/trait.VisitorMut.html b/p4/ast/trait.VisitorMut.html new file mode 100644 index 00000000..ee85937b --- /dev/null +++ b/p4/ast/trait.VisitorMut.html @@ -0,0 +1,39 @@ +VisitorMut in p4::ast - Rust +

Trait p4::ast::VisitorMut

source ·
pub trait VisitorMut {
+
Show 35 methods // Provided methods + fn constant(&mut self, _: &Constant) { ... } + fn header(&mut self, _: &Header) { ... } + fn p4struct(&mut self, _: &Struct) { ... } + fn typedef(&mut self, _: &Typedef) { ... } + fn control(&mut self, _: &Control) { ... } + fn parser(&mut self, _: &Parser) { ... } + fn package(&mut self, _: &Package) { ... } + fn package_instance(&mut self, _: &PackageInstance) { ... } + fn p4extern(&mut self, _: &Extern) { ... } + fn statement(&mut self, _: &Statement) { ... } + fn action(&mut self, _: &Action) { ... } + fn control_parameter(&mut self, _: &ControlParameter) { ... } + fn action_parameter(&mut self, _: &ActionParameter) { ... } + fn expression(&mut self, _: &Expression) { ... } + fn header_member(&mut self, _: &HeaderMember) { ... } + fn struct_member(&mut self, _: &StructMember) { ... } + fn call(&mut self, _: &Call) { ... } + fn typ(&mut self, _: &Type) { ... } + fn binop(&mut self, _: &BinOp) { ... } + fn lvalue(&mut self, _: &Lvalue) { ... } + fn variable(&mut self, _: &Variable) { ... } + fn if_block(&mut self, _: &IfBlock) { ... } + fn else_if_block(&mut self, _: &ElseIfBlock) { ... } + fn transition(&mut self, _: &Transition) { ... } + fn select(&mut self, _: &Select) { ... } + fn select_element(&mut self, _: &SelectElement) { ... } + fn key_set_element(&mut self, _: &KeySetElement) { ... } + fn key_set_element_value(&mut self, _: &KeySetElementValue) { ... } + fn table(&mut self, _: &Table) { ... } + fn match_kind(&mut self, _: &MatchKind) { ... } + fn const_table_entry(&mut self, _: &ConstTableEntry) { ... } + fn action_ref(&mut self, _: &ActionRef) { ... } + fn state(&mut self, _: &State) { ... } + fn package_parameter(&mut self, _: &PackageParameter) { ... } + fn extern_method(&mut self, _: &ExternMethod) { ... } +
}

Provided Methods§

source

fn constant(&mut self, _: &Constant)

source

fn header(&mut self, _: &Header)

source

fn p4struct(&mut self, _: &Struct)

source

fn typedef(&mut self, _: &Typedef)

source

fn control(&mut self, _: &Control)

source

fn parser(&mut self, _: &Parser)

source

fn package(&mut self, _: &Package)

source

fn package_instance(&mut self, _: &PackageInstance)

source

fn p4extern(&mut self, _: &Extern)

source

fn statement(&mut self, _: &Statement)

source

fn action(&mut self, _: &Action)

source

fn control_parameter(&mut self, _: &ControlParameter)

source

fn action_parameter(&mut self, _: &ActionParameter)

source

fn expression(&mut self, _: &Expression)

source

fn header_member(&mut self, _: &HeaderMember)

source

fn struct_member(&mut self, _: &StructMember)

source

fn call(&mut self, _: &Call)

source

fn typ(&mut self, _: &Type)

source

fn binop(&mut self, _: &BinOp)

source

fn lvalue(&mut self, _: &Lvalue)

source

fn variable(&mut self, _: &Variable)

source

fn if_block(&mut self, _: &IfBlock)

source

fn else_if_block(&mut self, _: &ElseIfBlock)

source

fn transition(&mut self, _: &Transition)

source

fn select(&mut self, _: &Select)

source

fn select_element(&mut self, _: &SelectElement)

source

fn key_set_element(&mut self, _: &KeySetElement)

source

fn key_set_element_value(&mut self, _: &KeySetElementValue)

source

fn table(&mut self, _: &Table)

source

fn match_kind(&mut self, _: &MatchKind)

source

fn const_table_entry(&mut self, _: &ConstTableEntry)

source

fn action_ref(&mut self, _: &ActionRef)

source

fn state(&mut self, _: &State)

source

fn package_parameter(&mut self, _: &PackageParameter)

source

fn extern_method(&mut self, _: &ExternMethod)

Implementors§

\ No newline at end of file diff --git a/p4/check/enum.Level.html b/p4/check/enum.Level.html new file mode 100644 index 00000000..c71649e5 --- /dev/null +++ b/p4/check/enum.Level.html @@ -0,0 +1,20 @@ +Level in p4::check - Rust +

Enum p4::check::Level

source ·
pub enum Level {
+    Info,
+    Deprecation,
+    Warning,
+    Error,
+}

Variants§

§

Info

§

Deprecation

§

Warning

§

Error

Trait Implementations§

source§

impl Clone for Level

source§

fn clone(&self) -> Level

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 Debug for Level

source§

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

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

impl PartialEq for Level

source§

fn eq(&self, other: &Level) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Level

source§

impl StructuralPartialEq for Level

Auto Trait Implementations§

§

impl RefUnwindSafe for Level

§

impl Send for Level

§

impl Sync for Level

§

impl Unpin for Level

§

impl UnwindSafe for Level

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/fn.all.html b/p4/check/fn.all.html new file mode 100644 index 00000000..ea2db4c7 --- /dev/null +++ b/p4/check/fn.all.html @@ -0,0 +1,2 @@ +all in p4::check - Rust +

Function p4::check::all

source ·
pub fn all(ast: &AST) -> (Hlir, Diagnostics)
\ No newline at end of file diff --git a/p4/check/index.html b/p4/check/index.html new file mode 100644 index 00000000..235f15fc --- /dev/null +++ b/p4/check/index.html @@ -0,0 +1,2 @@ +p4::check - Rust +
\ No newline at end of file diff --git a/p4/check/sidebar-items.js b/p4/check/sidebar-items.js new file mode 100644 index 00000000..da356aa1 --- /dev/null +++ b/p4/check/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Level"],"fn":["all"],"struct":["ApplyCallChecker","ControlChecker","Diagnostic","Diagnostics","ExpressionTypeChecker","HeaderChecker","ParserChecker","StructChecker"]}; \ No newline at end of file diff --git a/p4/check/struct.ApplyCallChecker.html b/p4/check/struct.ApplyCallChecker.html new file mode 100644 index 00000000..c80ce78b --- /dev/null +++ b/p4/check/struct.ApplyCallChecker.html @@ -0,0 +1,12 @@ +ApplyCallChecker in p4::check - Rust +

Struct p4::check::ApplyCallChecker

source ·
pub struct ApplyCallChecker<'a> { /* private fields */ }

Implementations§

source§

impl<'a> ApplyCallChecker<'a>

source

pub fn check_apply_table_apply(&mut self, _call: &Call, _tbl: &Table)

source

pub fn check_apply_ctl_apply(&mut self, call: &Call, ctl: &Control)

Trait Implementations§

source§

impl<'a> VisitorMut for ApplyCallChecker<'a>

source§

fn call(&mut self, call: &Call)

source§

fn constant(&mut self, _: &Constant)

source§

fn header(&mut self, _: &Header)

source§

fn p4struct(&mut self, _: &Struct)

source§

fn typedef(&mut self, _: &Typedef)

source§

fn control(&mut self, _: &Control)

source§

fn parser(&mut self, _: &Parser)

source§

fn package(&mut self, _: &Package)

source§

fn package_instance(&mut self, _: &PackageInstance)

source§

fn p4extern(&mut self, _: &Extern)

source§

fn statement(&mut self, _: &Statement)

source§

fn action(&mut self, _: &Action)

source§

fn control_parameter(&mut self, _: &ControlParameter)

source§

fn action_parameter(&mut self, _: &ActionParameter)

source§

fn expression(&mut self, _: &Expression)

source§

fn header_member(&mut self, _: &HeaderMember)

source§

fn struct_member(&mut self, _: &StructMember)

source§

fn typ(&mut self, _: &Type)

source§

fn binop(&mut self, _: &BinOp)

source§

fn lvalue(&mut self, _: &Lvalue)

source§

fn variable(&mut self, _: &Variable)

source§

fn if_block(&mut self, _: &IfBlock)

source§

fn else_if_block(&mut self, _: &ElseIfBlock)

source§

fn transition(&mut self, _: &Transition)

source§

fn select(&mut self, _: &Select)

source§

fn select_element(&mut self, _: &SelectElement)

source§

fn key_set_element(&mut self, _: &KeySetElement)

source§

fn key_set_element_value(&mut self, _: &KeySetElementValue)

source§

fn table(&mut self, _: &Table)

source§

fn match_kind(&mut self, _: &MatchKind)

source§

fn const_table_entry(&mut self, _: &ConstTableEntry)

source§

fn action_ref(&mut self, _: &ActionRef)

source§

fn state(&mut self, _: &State)

source§

fn package_parameter(&mut self, _: &PackageParameter)

source§

fn extern_method(&mut self, _: &ExternMethod)

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for ApplyCallChecker<'a>

§

impl<'a> Send for ApplyCallChecker<'a>

§

impl<'a> Sync for ApplyCallChecker<'a>

§

impl<'a> Unpin for ApplyCallChecker<'a>

§

impl<'a> !UnwindSafe for ApplyCallChecker<'a>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.ControlChecker.html b/p4/check/struct.ControlChecker.html new file mode 100644 index 00000000..2e1d3bf1 --- /dev/null +++ b/p4/check/struct.ControlChecker.html @@ -0,0 +1,33 @@ +ControlChecker in p4::check - Rust +

Struct p4::check::ControlChecker

source ·
pub struct ControlChecker {}

Implementations§

source§

impl ControlChecker

source

pub fn check(c: &Control, ast: &AST, hlir: &Hlir) -> Diagnostics

source

pub fn check_params(c: &Control, ast: &AST, diags: &mut Diagnostics)

source

pub fn check_tables( + c: &Control, + names: &HashMap<String, NameInfo>, + ast: &AST, + diags: &mut Diagnostics +)

source

pub fn check_table( + c: &Control, + t: &Table, + names: &HashMap<String, NameInfo>, + ast: &AST, + diags: &mut Diagnostics +)

source

pub fn check_variables(c: &Control, ast: &AST, diags: &mut Diagnostics)

source

pub fn check_actions( + c: &Control, + ast: &AST, + hlir: &Hlir, + diags: &mut Diagnostics +)

source

pub fn check_table_action_reference( + c: &Control, + t: &Table, + _ast: &AST, + diags: &mut Diagnostics +)

source

pub fn check_apply(c: &Control, ast: &AST, hlir: &Hlir, diags: &mut Diagnostics)

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.Diagnostic.html b/p4/check/struct.Diagnostic.html new file mode 100644 index 00000000..d554e594 --- /dev/null +++ b/p4/check/struct.Diagnostic.html @@ -0,0 +1,21 @@ +Diagnostic in p4::check - Rust +

Struct p4::check::Diagnostic

source ·
pub struct Diagnostic {
+    pub level: Level,
+    pub message: String,
+    pub token: Token,
+}

Fields§

§level: Level

Level of this diagnostic.

+
§message: String

Message associated with this diagnostic.

+
§token: Token

The first token from the lexical element where the semantic error was +detected.

+

Trait Implementations§

source§

impl Clone for Diagnostic

source§

fn clone(&self) -> Diagnostic

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 Debug for Diagnostic

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.Diagnostics.html b/p4/check/struct.Diagnostics.html new file mode 100644 index 00000000..0dd20164 --- /dev/null +++ b/p4/check/struct.Diagnostics.html @@ -0,0 +1,12 @@ +Diagnostics in p4::check - Rust +

Struct p4::check::Diagnostics

source ·
pub struct Diagnostics(pub Vec<Diagnostic>);

Tuple Fields§

§0: Vec<Diagnostic>

Implementations§

source§

impl Diagnostics

source

pub fn new() -> Self

source

pub fn errors(&self) -> Vec<&Diagnostic>

source

pub fn extend(&mut self, diags: &Diagnostics)

source

pub fn push(&mut self, d: Diagnostic)

Trait Implementations§

source§

impl Debug for Diagnostics

source§

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

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

impl Default for Diagnostics

source§

fn default() -> Diagnostics

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

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.ExpressionTypeChecker.html b/p4/check/struct.ExpressionTypeChecker.html new file mode 100644 index 00000000..4b05c891 --- /dev/null +++ b/p4/check/struct.ExpressionTypeChecker.html @@ -0,0 +1,20 @@ +ExpressionTypeChecker in p4::check - Rust +
pub struct ExpressionTypeChecker {}

Implementations§

source§

impl ExpressionTypeChecker

source

pub fn run(&self) -> (HashMap<Expression, Type>, Diagnostics)

source

pub fn check_constant(&self, _index: usize) -> Diagnostics

source

pub fn check_control(&self, _index: usize) -> Diagnostics

source

pub fn check_statement_block( + &self, + _sb: &mut StatementBlock, + _names: &HashMap<String, NameInfo> +) -> Diagnostics

source

pub fn check_expression( + &self, + _xpr: &mut Expression, + _names: &HashMap<String, NameInfo> +) -> Diagnostics

source

pub fn check_parser(&self, _index: usize) -> Diagnostics

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.HeaderChecker.html b/p4/check/struct.HeaderChecker.html new file mode 100644 index 00000000..47dfb707 --- /dev/null +++ b/p4/check/struct.HeaderChecker.html @@ -0,0 +1,12 @@ +HeaderChecker in p4::check - Rust +

Struct p4::check::HeaderChecker

source ·
pub struct HeaderChecker {}

Implementations§

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.ParserChecker.html b/p4/check/struct.ParserChecker.html new file mode 100644 index 00000000..f2989a89 --- /dev/null +++ b/p4/check/struct.ParserChecker.html @@ -0,0 +1,14 @@ +ParserChecker in p4::check - Rust +

Struct p4::check::ParserChecker

source ·
pub struct ParserChecker {}

Implementations§

source§

impl ParserChecker

source

pub fn check(p: &Parser, ast: &AST) -> Diagnostics

source

pub fn start_state(parser: &Parser, diags: &mut Diagnostics)

Ensure the parser has a start state

+
source

pub fn ensure_transition(state: &State, diags: &mut Diagnostics)

source

pub fn lvalues(parser: &Parser, ast: &AST, diags: &mut Diagnostics)

Check lvalue references

+

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/check/struct.StructChecker.html b/p4/check/struct.StructChecker.html new file mode 100644 index 00000000..2ffb6390 --- /dev/null +++ b/p4/check/struct.StructChecker.html @@ -0,0 +1,12 @@ +StructChecker in p4::check - Rust +

Struct p4::check::StructChecker

source ·
pub struct StructChecker {}

Implementations§

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/error/enum.Error.html b/p4/error/enum.Error.html new file mode 100644 index 00000000..5f329ba5 --- /dev/null +++ b/p4/error/enum.Error.html @@ -0,0 +1,17 @@ +Error in p4::error - Rust +

Enum p4::error::Error

source ·
pub enum Error {
+    Lexer(TokenError),
+    Parser(ParserError),
+    Semantic(Vec<SemanticError>),
+}

Variants§

Trait Implementations§

source§

impl Debug for Error

source§

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

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

impl Display for Error

source§

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

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

impl Error for Error

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ParserError> for Error

source§

fn from(e: ParserError) -> Self

Converts to this type from the input type.
source§

impl From<TokenError> for Error

source§

fn from(e: TokenError) -> Self

Converts to this type from the input type.
source§

impl From<Vec<SemanticError>> for Error

source§

fn from(e: Vec<SemanticError>) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

§

impl RefUnwindSafe for Error

§

impl Send for Error

§

impl Sync for Error

§

impl Unpin for Error

§

impl UnwindSafe for Error

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> 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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/error/index.html b/p4/error/index.html new file mode 100644 index 00000000..c373f55d --- /dev/null +++ b/p4/error/index.html @@ -0,0 +1,2 @@ +p4::error - Rust +
\ No newline at end of file diff --git a/p4/error/sidebar-items.js b/p4/error/sidebar-items.js new file mode 100644 index 00000000..55e45e68 --- /dev/null +++ b/p4/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Error"],"struct":["ParserError","PreprocessorError","SemanticError","TokenError"]}; \ No newline at end of file diff --git a/p4/error/struct.ParserError.html b/p4/error/struct.ParserError.html new file mode 100644 index 00000000..874219ca --- /dev/null +++ b/p4/error/struct.ParserError.html @@ -0,0 +1,20 @@ +ParserError in p4::error - Rust +

Struct p4::error::ParserError

source ·
pub struct ParserError {
+    pub at: Token,
+    pub message: String,
+    pub source: String,
+}

Fields§

§at: Token

Token where the error was encountered

+
§message: String

Message associated with this error.

+
§source: String

The source line the token error occured on.

+

Trait Implementations§

source§

impl Debug for ParserError

source§

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

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

impl Display for ParserError

source§

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

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

impl Error for ParserError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<ParserError> for Error

source§

fn from(e: ParserError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

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> 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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/error/struct.PreprocessorError.html b/p4/error/struct.PreprocessorError.html new file mode 100644 index 00000000..c1a00c09 --- /dev/null +++ b/p4/error/struct.PreprocessorError.html @@ -0,0 +1,22 @@ +PreprocessorError in p4::error - Rust +

Struct p4::error::PreprocessorError

source ·
pub struct PreprocessorError {
+    pub line: usize,
+    pub message: String,
+    pub source: String,
+    pub file: Arc<String>,
+}

Fields§

§line: usize

Token where the error was encountered

+
§message: String

Message associated with this error.

+
§source: String

The source line the token error occured on.

+
§file: Arc<String>

The soruce file where the token error was encountered.

+

Trait Implementations§

source§

impl Debug for PreprocessorError

source§

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

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

impl Display for PreprocessorError

source§

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

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

impl Error for PreprocessorError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

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> 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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/error/struct.SemanticError.html b/p4/error/struct.SemanticError.html new file mode 100644 index 00000000..0f182b5e --- /dev/null +++ b/p4/error/struct.SemanticError.html @@ -0,0 +1,20 @@ +SemanticError in p4::error - Rust +

Struct p4::error::SemanticError

source ·
pub struct SemanticError {
+    pub at: Token,
+    pub message: String,
+    pub source: String,
+}

Fields§

§at: Token

Token where the error was encountered

+
§message: String

Message associated with this error.

+
§source: String

The source line the token error occured on.

+

Trait Implementations§

source§

impl Debug for SemanticError

source§

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

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

impl Display for SemanticError

source§

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

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

impl Error for SemanticError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

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> 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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/error/struct.TokenError.html b/p4/error/struct.TokenError.html new file mode 100644 index 00000000..093fd0a3 --- /dev/null +++ b/p4/error/struct.TokenError.html @@ -0,0 +1,24 @@ +TokenError in p4::error - Rust +

Struct p4::error::TokenError

source ·
pub struct TokenError {
+    pub line: usize,
+    pub col: usize,
+    pub len: usize,
+    pub source: String,
+    pub file: Arc<String>,
+}

Fields§

§line: usize

Line where the token error was encountered.

+
§col: usize

Column where the token error was encountered.

+
§len: usize

Length of the erronious token.

+
§source: String

The source line the token error occured on.

+
§file: Arc<String>

The soruce file where the token error was encountered.

+

Trait Implementations§

source§

impl Debug for TokenError

source§

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

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

impl Display for TokenError

source§

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

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

impl Error for TokenError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<TokenError> for Error

source§

fn from(e: TokenError) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

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> 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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/hlir/index.html b/p4/hlir/index.html new file mode 100644 index 00000000..78e3c6c3 --- /dev/null +++ b/p4/hlir/index.html @@ -0,0 +1,4 @@ +p4::hlir - Rust +

Module p4::hlir

source ·

Structs§

  • The P4 high level intermediate representation (hlir) is a slight lowering of +the abstract syntax tree (ast) into something a bit more concreate. In +particular
\ No newline at end of file diff --git a/p4/hlir/sidebar-items.js b/p4/hlir/sidebar-items.js new file mode 100644 index 00000000..e6f704b6 --- /dev/null +++ b/p4/hlir/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Hlir","HlirGenerator"]}; \ No newline at end of file diff --git a/p4/hlir/struct.Hlir.html b/p4/hlir/struct.Hlir.html new file mode 100644 index 00000000..9c985d65 --- /dev/null +++ b/p4/hlir/struct.Hlir.html @@ -0,0 +1,25 @@ +Hlir in p4::hlir - Rust +

Struct p4::hlir::Hlir

source ·
pub struct Hlir {
+    pub expression_types: HashMap<Expression, Type>,
+    pub lvalue_decls: HashMap<Lvalue, NameInfo>,
+}
Expand description

The P4 high level intermediate representation (hlir) is a slight lowering of +the abstract syntax tree (ast) into something a bit more concreate. In +particular

+
    +
  • Types are resolved for expressions.
  • +
  • Lvalue names resolved to declarations.
  • +
+

The hlir maps language elements onto the corresponding type and declaration +information. Langauge elements contain lexical token members which ensure +hashing uniquenes.

+

Fields§

§expression_types: HashMap<Expression, Type>§lvalue_decls: HashMap<Lvalue, NameInfo>

Trait Implementations§

source§

impl Debug for Hlir

source§

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

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

impl Default for Hlir

source§

fn default() -> Hlir

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

Auto Trait Implementations§

§

impl RefUnwindSafe for Hlir

§

impl Send for Hlir

§

impl Sync for Hlir

§

impl Unpin for Hlir

§

impl UnwindSafe for Hlir

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/hlir/struct.HlirGenerator.html b/p4/hlir/struct.HlirGenerator.html new file mode 100644 index 00000000..ba2a4bdf --- /dev/null +++ b/p4/hlir/struct.HlirGenerator.html @@ -0,0 +1,16 @@ +HlirGenerator in p4::hlir - Rust +

Struct p4::hlir::HlirGenerator

source ·
pub struct HlirGenerator<'a> {
+    pub hlir: Hlir,
+    pub diags: Diagnostics,
+    /* private fields */
+}

Fields§

§hlir: Hlir§diags: Diagnostics

Implementations§

source§

impl<'a> HlirGenerator<'a>

source

pub fn new(ast: &'a AST) -> Self

source

pub fn run(&mut self)

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for HlirGenerator<'a>

§

impl<'a> Send for HlirGenerator<'a>

§

impl<'a> Sync for HlirGenerator<'a>

§

impl<'a> Unpin for HlirGenerator<'a>

§

impl<'a> UnwindSafe for HlirGenerator<'a>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/index.html b/p4/index.html new file mode 100644 index 00000000..1e258f64 --- /dev/null +++ b/p4/index.html @@ -0,0 +1,3 @@ +p4 - Rust +
\ No newline at end of file diff --git a/p4/lexer/enum.Kind.html b/p4/lexer/enum.Kind.html new file mode 100644 index 00000000..41a8b762 --- /dev/null +++ b/p4/lexer/enum.Kind.html @@ -0,0 +1,114 @@ +Kind in p4::lexer - Rust +

Enum p4::lexer::Kind

source ·
pub enum Kind {
+
Show 76 variants Const, + Header, + Typedef, + Control, + Struct, + Action, + Parser, + Table, + Size, + Key, + Exact, + Ternary, + Lpm, + Range, + Actions, + DefaultAction, + Entries, + In, + InOut, + Out, + Transition, + State, + Select, + Apply, + Package, + Extern, + If, + Else, + Return, + Bool, + Error, + Bit, + Varbit, + Int, + String, + AngleOpen, + AngleClose, + CurlyOpen, + CurlyClose, + ParenOpen, + ParenClose, + SquareOpen, + SquareClose, + Semicolon, + Comma, + Colon, + Underscore, + PoundInclude, + PoundDefine, + Backslash, + Forwardslash, + DoubleEquals, + NotEquals, + Equals, + Plus, + Minus, + Mod, + Dot, + Mask, + LogicalAnd, + And, + Bang, + Tilde, + Shl, + Pipe, + Carat, + GreaterThanEquals, + LessThanEquals, + IntLiteral(i128), + Identifier(String), + BitLiteral(u16, u128), + SignedLiteral(u16, i128), + TrueLiteral, + FalseLiteral, + StringLiteral(String), + Eof, +
}

Variants§

§

Const

§

Header

§

Typedef

§

Control

§

Struct

§

Action

§

Parser

§

Table

§

Size

§

Key

§

Exact

§

Ternary

§

Lpm

§

Range

§

Actions

§

DefaultAction

§

Entries

§

In

§

InOut

§

Out

§

Transition

§

State

§

Select

§

Apply

§

Package

§

Extern

§

If

§

Else

§

Return

§

Bool

§

Error

§

Bit

§

Varbit

§

Int

§

String

§

AngleOpen

§

AngleClose

§

CurlyOpen

§

CurlyClose

§

ParenOpen

§

ParenClose

§

SquareOpen

§

SquareClose

§

Semicolon

§

Comma

§

Colon

§

Underscore

§

PoundInclude

§

PoundDefine

§

Backslash

§

Forwardslash

§

DoubleEquals

§

NotEquals

§

Equals

§

Plus

§

Minus

§

Mod

§

Dot

§

Mask

§

LogicalAnd

§

And

§

Bang

§

Tilde

§

Shl

§

Pipe

§

Carat

§

GreaterThanEquals

§

LessThanEquals

§

IntLiteral(i128)

An integer literal. The following are literal examples and their +associated types. +- 10 : int +- 8s10 : int<8> +- 2s3 : int<2> +- 1s1 : int<1>

+
§

Identifier(String)

§

BitLiteral(u16, u128)

A bit literal. The following a literal examples and their associated +types. +- 8w10 : bit<8> +- 1w1 : bit<1> +First element is number of bits (prefix before w) second element is +value (suffix after w).

+
§

SignedLiteral(u16, i128)

A signed literal. The following a literal examples and their associated +types. +- 8s10 : bit<8> +- 1s1 : bit<1> +First element is number of bits (prefix before w) second element is +value (suffix after w).

+
§

TrueLiteral

§

FalseLiteral

§

StringLiteral(String)

§

Eof

End of file.

+

Trait Implementations§

source§

impl Clone for Kind

source§

fn clone(&self) -> Kind

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 Debug for Kind

source§

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

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

impl Display for Kind

source§

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

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

impl Hash for Kind

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Kind

source§

fn eq(&self, other: &Kind) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Kind

source§

impl StructuralPartialEq for Kind

Auto Trait Implementations§

§

impl RefUnwindSafe for Kind

§

impl Send for Kind

§

impl Sync for Kind

§

impl Unpin for Kind

§

impl UnwindSafe for Kind

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> 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,

§

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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/lexer/index.html b/p4/lexer/index.html new file mode 100644 index 00000000..2329b01c --- /dev/null +++ b/p4/lexer/index.html @@ -0,0 +1,2 @@ +p4::lexer - Rust +

Module p4::lexer

source ·

Structs§

Enums§

\ No newline at end of file diff --git a/p4/lexer/sidebar-items.js b/p4/lexer/sidebar-items.js new file mode 100644 index 00000000..96792dbe --- /dev/null +++ b/p4/lexer/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Kind"],"struct":["Lexer","Token"]}; \ No newline at end of file diff --git a/p4/lexer/struct.Lexer.html b/p4/lexer/struct.Lexer.html new file mode 100644 index 00000000..088d55e0 --- /dev/null +++ b/p4/lexer/struct.Lexer.html @@ -0,0 +1,17 @@ +Lexer in p4::lexer - Rust +

Struct p4::lexer::Lexer

source ·
pub struct Lexer<'a> {
+    pub line: usize,
+    pub col: usize,
+    pub show_tokens: bool,
+    /* private fields */
+}

Fields§

§line: usize§col: usize§show_tokens: bool

Implementations§

source§

impl<'a> Lexer<'a>

source

pub fn new(lines: Vec<&'a str>, filename: Arc<String>) -> Self

source

pub fn next(&mut self) -> Result<Token, TokenError>

source

pub fn check_end_of_line(&mut self) -> bool

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Lexer<'a>

§

impl<'a> Send for Lexer<'a>

§

impl<'a> Sync for Lexer<'a>

§

impl<'a> Unpin for Lexer<'a>

§

impl<'a> UnwindSafe for Lexer<'a>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/lexer/struct.Token.html b/p4/lexer/struct.Token.html new file mode 100644 index 00000000..86237a50 --- /dev/null +++ b/p4/lexer/struct.Token.html @@ -0,0 +1,27 @@ +Token in p4::lexer - Rust +

Struct p4::lexer::Token

source ·
pub struct Token {
+    pub kind: Kind,
+    pub line: usize,
+    pub col: usize,
+    pub file: Arc<String>,
+}

Fields§

§kind: Kind

The kind of token this is.

+
§line: usize

Line number of this token.

+
§col: usize

Column number of the first character in this token.

+
§file: Arc<String>

The file this token came from.

+

Trait Implementations§

source§

impl Clone for Token

source§

fn clone(&self) -> Token

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 Debug for Token

source§

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

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

impl Display for Token

source§

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

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

impl Hash for Token

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Token

source§

fn eq(&self, other: &Token) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for Token

source§

impl StructuralPartialEq for Token

Auto Trait Implementations§

§

impl RefUnwindSafe for Token

§

impl Send for Token

§

impl Sync for Token

§

impl Unpin for Token

§

impl UnwindSafe for Token

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> 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,

§

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> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/index.html b/p4/parser/index.html new file mode 100644 index 00000000..64be00ba --- /dev/null +++ b/p4/parser/index.html @@ -0,0 +1,2 @@ +p4::parser - Rust +

Module p4::parser

source ·

Structs§

\ No newline at end of file diff --git a/p4/parser/sidebar-items.js b/p4/parser/sidebar-items.js new file mode 100644 index 00000000..47fc5c5a --- /dev/null +++ b/p4/parser/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["ActionParser","ControlParser","ExpressionParser","GlobalParser","IfElseParser","Parser","ParserParser","SelectParser","StateParser","StatementParser","TableParser"]}; \ No newline at end of file diff --git a/p4/parser/struct.ActionParser.html b/p4/parser/struct.ActionParser.html new file mode 100644 index 00000000..7c1467ef --- /dev/null +++ b/p4/parser/struct.ActionParser.html @@ -0,0 +1,12 @@ +ActionParser in p4::parser - Rust +

Struct p4::parser::ActionParser

source ·
pub struct ActionParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> ActionParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Action, Error>

source

pub fn parse_parameters(&mut self, action: &mut Action) -> Result<(), Error>

source

pub fn parse_sized_variable(&mut self, _ty: Type) -> Result<Variable, Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for ActionParser<'a, 'b>

§

impl<'a, 'b> Send for ActionParser<'a, 'b>

§

impl<'a, 'b> Sync for ActionParser<'a, 'b>

§

impl<'a, 'b> Unpin for ActionParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for ActionParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.ControlParser.html b/p4/parser/struct.ControlParser.html new file mode 100644 index 00000000..47a10892 --- /dev/null +++ b/p4/parser/struct.ControlParser.html @@ -0,0 +1,13 @@ +ControlParser in p4::parser - Rust +

Struct p4::parser::ControlParser

source ·
pub struct ControlParser<'a, 'b> { /* private fields */ }
Expand description

Parser for parsing control definitions

+

Implementations§

source§

impl<'a, 'b> ControlParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Control, Error>

source

pub fn parse_body(&mut self, control: &mut Control) -> Result<(), Error>

source

pub fn parse_action(&mut self, control: &mut Control) -> Result<(), Error>

source

pub fn parse_table(&mut self, control: &mut Control) -> Result<(), Error>

source

pub fn parse_apply(&mut self, control: &mut Control) -> Result<(), Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for ControlParser<'a, 'b>

§

impl<'a, 'b> Send for ControlParser<'a, 'b>

§

impl<'a, 'b> Sync for ControlParser<'a, 'b>

§

impl<'a, 'b> Unpin for ControlParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for ControlParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.ExpressionParser.html b/p4/parser/struct.ExpressionParser.html new file mode 100644 index 00000000..fac99f9f --- /dev/null +++ b/p4/parser/struct.ExpressionParser.html @@ -0,0 +1,12 @@ +ExpressionParser in p4::parser - Rust +

Struct p4::parser::ExpressionParser

source ·
pub struct ExpressionParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> ExpressionParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Box<Expression>, Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for ExpressionParser<'a, 'b>

§

impl<'a, 'b> Send for ExpressionParser<'a, 'b>

§

impl<'a, 'b> Sync for ExpressionParser<'a, 'b>

§

impl<'a, 'b> Unpin for ExpressionParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for ExpressionParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.GlobalParser.html b/p4/parser/struct.GlobalParser.html new file mode 100644 index 00000000..76ef6a61 --- /dev/null +++ b/p4/parser/struct.GlobalParser.html @@ -0,0 +1,24 @@ +GlobalParser in p4::parser - Rust +

Struct p4::parser::GlobalParser

source ·
pub struct GlobalParser<'a, 'b> { /* private fields */ }
Expand description

Top level parser for parsing elements are global scope.

+

Implementations§

source§

impl<'a, 'b> GlobalParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&'b mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_token(&mut self, token: Token, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_const_decl(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_header_decl(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_struct_decl(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_typedef(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_control(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_parser( + &mut self, + ast: &mut AST, + start: Token +) -> Result<(), Error>

source

pub fn handle_package(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn handle_extern(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn parse_package_parameters( + &mut self, + pkg: &mut Package +) -> Result<(), Error>

source

pub fn handle_package_instance( + &mut self, + typ: String, + ast: &mut AST +) -> Result<(), Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for GlobalParser<'a, 'b>

§

impl<'a, 'b> Send for GlobalParser<'a, 'b>

§

impl<'a, 'b> Sync for GlobalParser<'a, 'b>

§

impl<'a, 'b> Unpin for GlobalParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for GlobalParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.IfElseParser.html b/p4/parser/struct.IfElseParser.html new file mode 100644 index 00000000..e6e8082f --- /dev/null +++ b/p4/parser/struct.IfElseParser.html @@ -0,0 +1,12 @@ +IfElseParser in p4::parser - Rust +

Struct p4::parser::IfElseParser

source ·
pub struct IfElseParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> IfElseParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Statement, Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for IfElseParser<'a, 'b>

§

impl<'a, 'b> Send for IfElseParser<'a, 'b>

§

impl<'a, 'b> Sync for IfElseParser<'a, 'b>

§

impl<'a, 'b> Unpin for IfElseParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for IfElseParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.Parser.html b/p4/parser/struct.Parser.html new file mode 100644 index 00000000..d5ee7fe6 --- /dev/null +++ b/p4/parser/struct.Parser.html @@ -0,0 +1,13 @@ +Parser in p4::parser - Rust +

Struct p4::parser::Parser

source ·
pub struct Parser<'a> { /* private fields */ }
Expand description

This is a recurisve descent parser for the P4 language.

+

Implementations§

source§

impl<'a> Parser<'a>

source

pub fn new(lexer: Lexer<'a>) -> Self

source

pub fn run(&mut self, ast: &mut AST) -> Result<(), Error>

source

pub fn next_token(&mut self) -> Result<Token, Error>

source

pub fn parse_direction(&mut self) -> Result<(Direction, Token), Error>

source

pub fn parse_variable(&mut self) -> Result<Variable, Error>

source

pub fn parse_constant(&mut self) -> Result<Constant, Error>

source

pub fn parse_expression(&mut self) -> Result<Box<Expression>, Error>

source

pub fn parse_keyset(&mut self) -> Result<Vec<KeySetElement>, Error>

source

pub fn parse_expr_parameters(&mut self) -> Result<Vec<Box<Expression>>, Error>

source

pub fn parse_statement_block(&mut self) -> Result<StatementBlock, Error>

source

pub fn parse_transition(&mut self) -> Result<Transition, Error>

source

pub fn parse_parameters(&mut self) -> Result<Vec<ControlParameter>, Error>

source

pub fn parse_type_parameters(&mut self) -> Result<Vec<String>, Error>

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for Parser<'a>

§

impl<'a> Send for Parser<'a>

§

impl<'a> Sync for Parser<'a>

§

impl<'a> Unpin for Parser<'a>

§

impl<'a> UnwindSafe for Parser<'a>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.ParserParser.html b/p4/parser/struct.ParserParser.html new file mode 100644 index 00000000..4b2d94cf --- /dev/null +++ b/p4/parser/struct.ParserParser.html @@ -0,0 +1,13 @@ +ParserParser in p4::parser - Rust +

Struct p4::parser::ParserParser

source ·
pub struct ParserParser<'a, 'b> { /* private fields */ }
Expand description

Parser for parsing parser definitions

+

Implementations§

source§

impl<'a, 'b> ParserParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>, start: Token) -> Self

source

pub fn run(&mut self) -> Result<Parser, Error>

source

pub fn parse_parameters(&mut self, parser: &mut Parser) -> Result<(), Error>

source

pub fn parse_body(&mut self, parser: &mut Parser) -> Result<(), Error>

source

pub fn parse_state(&mut self, parser: &mut Parser) -> Result<(), Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for ParserParser<'a, 'b>

§

impl<'a, 'b> Send for ParserParser<'a, 'b>

§

impl<'a, 'b> Sync for ParserParser<'a, 'b>

§

impl<'a, 'b> Unpin for ParserParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for ParserParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.SelectParser.html b/p4/parser/struct.SelectParser.html new file mode 100644 index 00000000..081625d3 --- /dev/null +++ b/p4/parser/struct.SelectParser.html @@ -0,0 +1,12 @@ +SelectParser in p4::parser - Rust +

Struct p4::parser::SelectParser

source ·
pub struct SelectParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> SelectParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Select, Error>

source

pub fn parse_body(&mut self, select: &mut Select) -> Result<(), Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for SelectParser<'a, 'b>

§

impl<'a, 'b> Send for SelectParser<'a, 'b>

§

impl<'a, 'b> Sync for SelectParser<'a, 'b>

§

impl<'a, 'b> Unpin for SelectParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for SelectParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.StateParser.html b/p4/parser/struct.StateParser.html new file mode 100644 index 00000000..51441525 --- /dev/null +++ b/p4/parser/struct.StateParser.html @@ -0,0 +1,12 @@ +StateParser in p4::parser - Rust +

Struct p4::parser::StateParser

source ·
pub struct StateParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> StateParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<State, Error>

source

pub fn parse_body(&mut self, state: &mut State) -> Result<(), Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for StateParser<'a, 'b>

§

impl<'a, 'b> Send for StateParser<'a, 'b>

§

impl<'a, 'b> Sync for StateParser<'a, 'b>

§

impl<'a, 'b> Unpin for StateParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for StateParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.StatementParser.html b/p4/parser/struct.StatementParser.html new file mode 100644 index 00000000..964ecf50 --- /dev/null +++ b/p4/parser/struct.StatementParser.html @@ -0,0 +1,15 @@ +StatementParser in p4::parser - Rust +

Struct p4::parser::StatementParser

source ·
pub struct StatementParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> StatementParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Statement, Error>

source

pub fn parse_assignment(&mut self, lval: Lvalue) -> Result<Statement, Error>

source

pub fn parse_call(&mut self, lval: Lvalue) -> Result<Statement, Error>

source

pub fn parse_parameterized_call( + &mut self, + _lval: Lvalue +) -> Result<Statement, Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for StatementParser<'a, 'b>

§

impl<'a, 'b> Send for StatementParser<'a, 'b>

§

impl<'a, 'b> Sync for StatementParser<'a, 'b>

§

impl<'a, 'b> Unpin for StatementParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for StatementParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/parser/struct.TableParser.html b/p4/parser/struct.TableParser.html new file mode 100644 index 00000000..8af7cee6 --- /dev/null +++ b/p4/parser/struct.TableParser.html @@ -0,0 +1,12 @@ +TableParser in p4::parser - Rust +

Struct p4::parser::TableParser

source ·
pub struct TableParser<'a, 'b> { /* private fields */ }

Implementations§

source§

impl<'a, 'b> TableParser<'a, 'b>

source

pub fn new(parser: &'b mut Parser<'a>) -> Self

source

pub fn run(&mut self) -> Result<Table, Error>

source

pub fn parse_body(&mut self, table: &mut Table) -> Result<(), Error>

source

pub fn parse_key(&mut self, table: &mut Table) -> Result<(), Error>

source

pub fn parse_match_kind(&mut self) -> Result<MatchKind, Error>

source

pub fn parse_actions(&mut self, table: &mut Table) -> Result<(), Error>

source

pub fn parse_default_action(&mut self, table: &mut Table) -> Result<(), Error>

source

pub fn parse_entries(&mut self, table: &mut Table) -> Result<(), Error>

source

pub fn parse_entry(&mut self) -> Result<ConstTableEntry, Error>

source

pub fn parse_actionref(&mut self) -> Result<ActionRef, Error>

Auto Trait Implementations§

§

impl<'a, 'b> RefUnwindSafe for TableParser<'a, 'b>

§

impl<'a, 'b> Send for TableParser<'a, 'b>

§

impl<'a, 'b> Sync for TableParser<'a, 'b>

§

impl<'a, 'b> Unpin for TableParser<'a, 'b>

§

impl<'a, 'b> !UnwindSafe for TableParser<'a, 'b>

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/preprocessor/fn.run.html b/p4/preprocessor/fn.run.html new file mode 100644 index 00000000..3acad647 --- /dev/null +++ b/p4/preprocessor/fn.run.html @@ -0,0 +1,5 @@ +run in p4::preprocessor - Rust +

Function p4::preprocessor::run

source ·
pub fn run(
+    source: &str,
+    filename: Arc<String>
+) -> Result<PreprocessorResult, PreprocessorError>
\ No newline at end of file diff --git a/p4/preprocessor/index.html b/p4/preprocessor/index.html new file mode 100644 index 00000000..8ae12fc2 --- /dev/null +++ b/p4/preprocessor/index.html @@ -0,0 +1,2 @@ +p4::preprocessor - Rust +
\ No newline at end of file diff --git a/p4/preprocessor/sidebar-items.js b/p4/preprocessor/sidebar-items.js new file mode 100644 index 00000000..f13d5274 --- /dev/null +++ b/p4/preprocessor/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["run"],"struct":["PreprocessorElements","PreprocessorResult"]}; \ No newline at end of file diff --git a/p4/preprocessor/struct.PreprocessorElements.html b/p4/preprocessor/struct.PreprocessorElements.html new file mode 100644 index 00000000..f29e690a --- /dev/null +++ b/p4/preprocessor/struct.PreprocessorElements.html @@ -0,0 +1,14 @@ +PreprocessorElements in p4::preprocessor - Rust +
pub struct PreprocessorElements {
+    pub includes: Vec<String>,
+}

Fields§

§includes: Vec<String>

Trait Implementations§

source§

impl Debug for PreprocessorElements

source§

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

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

impl Default for PreprocessorElements

source§

fn default() -> PreprocessorElements

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

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/preprocessor/struct.PreprocessorResult.html b/p4/preprocessor/struct.PreprocessorResult.html new file mode 100644 index 00000000..438dc667 --- /dev/null +++ b/p4/preprocessor/struct.PreprocessorResult.html @@ -0,0 +1,15 @@ +PreprocessorResult in p4::preprocessor - Rust +
pub struct PreprocessorResult {
+    pub elements: PreprocessorElements,
+    pub lines: Vec<String>,
+}

Fields§

§elements: PreprocessorElements§lines: Vec<String>

Trait Implementations§

source§

impl Debug for PreprocessorResult

source§

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

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

impl Default for PreprocessorResult

source§

fn default() -> PreprocessorResult

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

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4/sidebar-items.js b/p4/sidebar-items.js new file mode 100644 index 00000000..90ee7b73 --- /dev/null +++ b/p4/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["ast","check","error","hlir","lexer","parser","preprocessor","util"]}; \ No newline at end of file diff --git a/p4/util/fn.resolve_lvalue.html b/p4/util/fn.resolve_lvalue.html new file mode 100644 index 00000000..ee8c0bd4 --- /dev/null +++ b/p4/util/fn.resolve_lvalue.html @@ -0,0 +1,6 @@ +resolve_lvalue in p4::util - Rust +

Function p4::util::resolve_lvalue

source ·
pub fn resolve_lvalue(
+    lval: &Lvalue,
+    ast: &AST,
+    names: &HashMap<String, NameInfo>
+) -> Result<NameInfo, String>
\ No newline at end of file diff --git a/p4/util/index.html b/p4/util/index.html new file mode 100644 index 00000000..fc93f168 --- /dev/null +++ b/p4/util/index.html @@ -0,0 +1,2 @@ +p4::util - Rust +

Module p4::util

source ·

Functions§

\ No newline at end of file diff --git a/p4/util/sidebar-items.js b/p4/util/sidebar-items.js new file mode 100644 index 00000000..24aa3283 --- /dev/null +++ b/p4/util/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["resolve_lvalue"]}; \ No newline at end of file diff --git a/p4_macro/all.html b/p4_macro/all.html new file mode 100644 index 00000000..a44d6c42 --- /dev/null +++ b/p4_macro/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +

List of all items

Macros

\ No newline at end of file diff --git a/p4_macro/index.html b/p4_macro/index.html new file mode 100644 index 00000000..080784ac --- /dev/null +++ b/p4_macro/index.html @@ -0,0 +1,22 @@ +p4_macro - Rust +

Crate p4_macro

source ·
Expand description

The use_p4! macro allows for P4 programs to be directly integrated into +Rust programs.

+ +
p4_macro::use_p4!("path/to/p4/program.p4");
+

This will generate a main_pipeline struct that implements the +Pipeline trait. The use_p4! macro expands +directly in to x4c compiled code. This includes all data structures, +parsers and control blocks.

+

To customize the name of the generated pipeline use the pipeline_name +parameter.

+ +
p4_macro::use_p4!(p4 = "path/to/p4/program.p4", pipeline_name = "muffin");
+

This will result in a muffin_pipeline struct being being generated.

+

For documentation on using Pipeline trait, see the +p4rs docs.

+

Macros§

  • The use_p4! macro uses the x4c compiler to generate Rust code from a P4 +program. The macro itself expands into the generated code. The macro can be +called with only the path to the P4 program as an argument or, it can be +called with the path to the P4 program plus the name to use for the +generated pipeline object.
\ No newline at end of file diff --git a/p4_macro/macro.use_p4!.html b/p4_macro/macro.use_p4!.html new file mode 100644 index 00000000..868c7d18 --- /dev/null +++ b/p4_macro/macro.use_p4!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.use_p4.html...

+ + + \ No newline at end of file diff --git a/p4_macro/macro.use_p4.html b/p4_macro/macro.use_p4.html new file mode 100644 index 00000000..3581ad69 --- /dev/null +++ b/p4_macro/macro.use_p4.html @@ -0,0 +1,8 @@ +use_p4 in p4_macro - Rust +

Macro p4_macro::use_p4

source ·
use_p4!() { /* proc-macro */ }
Expand description

The use_p4! macro uses the x4c compiler to generate Rust code from a P4 +program. The macro itself expands into the generated code. The macro can be +called with only the path to the P4 program as an argument or, it can be +called with the path to the P4 program plus the name to use for the +generated pipeline object.

+

For usage examples, see the p4-macro module documentation.

+
\ No newline at end of file diff --git a/p4_macro/sidebar-items.js b/p4_macro/sidebar-items.js new file mode 100644 index 00000000..c390b0b5 --- /dev/null +++ b/p4_macro/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"macro":["use_p4"]}; \ No newline at end of file diff --git a/p4_macro_test/all.html b/p4_macro_test/all.html new file mode 100644 index 00000000..ac726a33 --- /dev/null +++ b/p4_macro_test/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/p4_macro_test/fn.main.html b/p4_macro_test/fn.main.html new file mode 100644 index 00000000..e5755b12 --- /dev/null +++ b/p4_macro_test/fn.main.html @@ -0,0 +1,2 @@ +main in p4_macro_test - Rust +

Function p4_macro_test::main

source ·
pub(crate) fn main()
\ No newline at end of file diff --git a/p4_macro_test/fn.parsadillo_start.html b/p4_macro_test/fn.parsadillo_start.html new file mode 100644 index 00000000..30861627 --- /dev/null +++ b/p4_macro_test/fn.parsadillo_start.html @@ -0,0 +1,5 @@ +parsadillo_start in p4_macro_test - Rust +
pub fn parsadillo_start(
+    pkt: &mut packet_in<'_>,
+    headers: &mut headers_t
+) -> bool
\ No newline at end of file diff --git a/p4_macro_test/index.html b/p4_macro_test/index.html new file mode 100644 index 00000000..273d61e6 --- /dev/null +++ b/p4_macro_test/index.html @@ -0,0 +1,3 @@ +p4_macro_test - Rust +
\ No newline at end of file diff --git a/p4_macro_test/sidebar-items.js b/p4_macro_test/sidebar-items.js new file mode 100644 index 00000000..59a260f0 --- /dev/null +++ b/p4_macro_test/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["main","parsadillo_start"],"mod":["softnpu_provider"],"struct":["ethernet_t","headers_t"]}; \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/index.html b/p4_macro_test/softnpu_provider/index.html new file mode 100644 index 00000000..daa9eaf7 --- /dev/null +++ b/p4_macro_test/softnpu_provider/index.html @@ -0,0 +1,2 @@ +p4_macro_test::softnpu_provider - Rust +
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.action!.html b/p4_macro_test/softnpu_provider/macro.action!.html new file mode 100644 index 00000000..d4ab696b --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.action!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.action.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.action.html b/p4_macro_test/softnpu_provider/macro.action.html new file mode 100644 index 00000000..32b49183 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.action.html @@ -0,0 +1,5 @@ +action in p4_macro_test::softnpu_provider - Rust +
macro_rules! action {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.control_apply!.html b/p4_macro_test/softnpu_provider/macro.control_apply!.html new file mode 100644 index 00000000..30ff9a1c --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.control_apply!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_apply.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.control_apply.html b/p4_macro_test/softnpu_provider/macro.control_apply.html new file mode 100644 index 00000000..4ac9febf --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.control_apply.html @@ -0,0 +1,5 @@ +control_apply in p4_macro_test::softnpu_provider - Rust +
macro_rules! control_apply {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.control_table_hit!.html b/p4_macro_test/softnpu_provider/macro.control_table_hit!.html new file mode 100644 index 00000000..b2c3113d --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.control_table_hit!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_table_hit.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.control_table_hit.html b/p4_macro_test/softnpu_provider/macro.control_table_hit.html new file mode 100644 index 00000000..dc864ea0 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.control_table_hit.html @@ -0,0 +1,5 @@ +control_table_hit in p4_macro_test::softnpu_provider - Rust +
macro_rules! control_table_hit {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.control_table_miss!.html b/p4_macro_test/softnpu_provider/macro.control_table_miss!.html new file mode 100644 index 00000000..6c9107c1 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.control_table_miss!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_table_miss.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.control_table_miss.html b/p4_macro_test/softnpu_provider/macro.control_table_miss.html new file mode 100644 index 00000000..1a80fc52 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.control_table_miss.html @@ -0,0 +1,5 @@ +control_table_miss in p4_macro_test::softnpu_provider - Rust +
macro_rules! control_table_miss {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_accepted!.html b/p4_macro_test/softnpu_provider/macro.egress_accepted!.html new file mode 100644 index 00000000..bd4b37c4 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_accepted.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_accepted.html b/p4_macro_test/softnpu_provider/macro.egress_accepted.html new file mode 100644 index 00000000..4402cdfe --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_accepted.html @@ -0,0 +1,5 @@ +egress_accepted in p4_macro_test::softnpu_provider - Rust +
macro_rules! egress_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_dropped!.html b/p4_macro_test/softnpu_provider/macro.egress_dropped!.html new file mode 100644 index 00000000..3045dc36 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_dropped.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_dropped.html b/p4_macro_test/softnpu_provider/macro.egress_dropped.html new file mode 100644 index 00000000..8a2d097a --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_dropped.html @@ -0,0 +1,5 @@ +egress_dropped in p4_macro_test::softnpu_provider - Rust +
macro_rules! egress_dropped {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_table_hit!.html b/p4_macro_test/softnpu_provider/macro.egress_table_hit!.html new file mode 100644 index 00000000..04b83478 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_table_hit!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_table_hit.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_table_hit.html b/p4_macro_test/softnpu_provider/macro.egress_table_hit.html new file mode 100644 index 00000000..168359c2 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_table_hit.html @@ -0,0 +1,5 @@ +egress_table_hit in p4_macro_test::softnpu_provider - Rust +
macro_rules! egress_table_hit {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_table_miss!.html b/p4_macro_test/softnpu_provider/macro.egress_table_miss!.html new file mode 100644 index 00000000..686d6e77 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_table_miss!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_table_miss.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.egress_table_miss.html b/p4_macro_test/softnpu_provider/macro.egress_table_miss.html new file mode 100644 index 00000000..b835dd71 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.egress_table_miss.html @@ -0,0 +1,5 @@ +egress_table_miss in p4_macro_test::softnpu_provider - Rust +
macro_rules! egress_table_miss {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.ingress_accepted!.html b/p4_macro_test/softnpu_provider/macro.ingress_accepted!.html new file mode 100644 index 00000000..0640a788 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.ingress_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.ingress_accepted.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.ingress_accepted.html b/p4_macro_test/softnpu_provider/macro.ingress_accepted.html new file mode 100644 index 00000000..299517f8 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.ingress_accepted.html @@ -0,0 +1,5 @@ +ingress_accepted in p4_macro_test::softnpu_provider - Rust +
macro_rules! ingress_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.ingress_dropped!.html b/p4_macro_test/softnpu_provider/macro.ingress_dropped!.html new file mode 100644 index 00000000..e0505f61 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.ingress_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.ingress_dropped.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.ingress_dropped.html b/p4_macro_test/softnpu_provider/macro.ingress_dropped.html new file mode 100644 index 00000000..bd37b89d --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.ingress_dropped.html @@ -0,0 +1,5 @@ +ingress_dropped in p4_macro_test::softnpu_provider - Rust +
macro_rules! ingress_dropped {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.parser_accepted!.html b/p4_macro_test/softnpu_provider/macro.parser_accepted!.html new file mode 100644 index 00000000..cfa1b466 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.parser_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_accepted.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.parser_accepted.html b/p4_macro_test/softnpu_provider/macro.parser_accepted.html new file mode 100644 index 00000000..1eef8d47 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.parser_accepted.html @@ -0,0 +1,5 @@ +parser_accepted in p4_macro_test::softnpu_provider - Rust +
macro_rules! parser_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.parser_dropped!.html b/p4_macro_test/softnpu_provider/macro.parser_dropped!.html new file mode 100644 index 00000000..de167747 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.parser_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_dropped.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.parser_dropped.html b/p4_macro_test/softnpu_provider/macro.parser_dropped.html new file mode 100644 index 00000000..2d585dc3 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.parser_dropped.html @@ -0,0 +1,6 @@ +parser_dropped in p4_macro_test::softnpu_provider - Rust +
macro_rules! parser_dropped {
+    () => { ... };
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.parser_transition!.html b/p4_macro_test/softnpu_provider/macro.parser_transition!.html new file mode 100644 index 00000000..605298f0 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.parser_transition!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_transition.html...

+ + + \ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/macro.parser_transition.html b/p4_macro_test/softnpu_provider/macro.parser_transition.html new file mode 100644 index 00000000..8c443da5 --- /dev/null +++ b/p4_macro_test/softnpu_provider/macro.parser_transition.html @@ -0,0 +1,5 @@ +parser_transition in p4_macro_test::softnpu_provider - Rust +
macro_rules! parser_transition {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/p4_macro_test/softnpu_provider/sidebar-items.js b/p4_macro_test/softnpu_provider/sidebar-items.js new file mode 100644 index 00000000..3e3f1355 --- /dev/null +++ b/p4_macro_test/softnpu_provider/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"macro":["action","control_apply","control_table_hit","control_table_miss","egress_accepted","egress_dropped","egress_table_hit","egress_table_miss","ingress_accepted","ingress_dropped","parser_accepted","parser_dropped","parser_transition"]}; \ No newline at end of file diff --git a/p4_macro_test/struct.ethernet_t.html b/p4_macro_test/struct.ethernet_t.html new file mode 100644 index 00000000..1f4620ab --- /dev/null +++ b/p4_macro_test/struct.ethernet_t.html @@ -0,0 +1,97 @@ +ethernet_t in p4_macro_test - Rust +
pub struct ethernet_t {
+    pub valid: bool,
+    pub dst_addr: BitVec<u8, Msb0>,
+    pub src_addr: BitVec<u8, Msb0>,
+    pub ether_type: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§dst_addr: BitVec<u8, Msb0>§src_addr: BitVec<u8, Msb0>§ether_type: BitVec<u8, Msb0>

Implementations§

source§

impl ethernet_t

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ethernet_t

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ethernet_t

source§

fn clone(&self) -> ethernet_t

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 Debug for ethernet_t

source§

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

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

impl Default for ethernet_t

source§

fn default() -> ethernet_t

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

impl Header for ethernet_t

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4_macro_test/struct.headers_t.html b/p4_macro_test/struct.headers_t.html new file mode 100644 index 00000000..12563883 --- /dev/null +++ b/p4_macro_test/struct.headers_t.html @@ -0,0 +1,94 @@ +headers_t in p4_macro_test - Rust +
pub struct headers_t {
+    pub ethernet: ethernet_t,
+}

Fields§

§ethernet: ethernet_t

Implementations§

source§

impl headers_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for headers_t

source§

fn clone(&self) -> headers_t

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 Debug for headers_t

source§

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

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

impl Default for headers_t

source§

fn default() -> headers_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4_rust/all.html b/p4_rust/all.html new file mode 100644 index 00000000..71172560 --- /dev/null +++ b/p4_rust/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +

List of all items

Structs

Functions

\ No newline at end of file diff --git a/p4_rust/fn.emit.html b/p4_rust/fn.emit.html new file mode 100644 index 00000000..0d12aa22 --- /dev/null +++ b/p4_rust/fn.emit.html @@ -0,0 +1,7 @@ +emit in p4_rust - Rust +

Function p4_rust::emit

source ·
pub fn emit(
+    ast: &AST,
+    hlir: &Hlir,
+    filename: &str,
+    settings: Settings
+) -> Result<()>
\ No newline at end of file diff --git a/p4_rust/fn.emit_tokens.html b/p4_rust/fn.emit_tokens.html new file mode 100644 index 00000000..1c9874a8 --- /dev/null +++ b/p4_rust/fn.emit_tokens.html @@ -0,0 +1,2 @@ +emit_tokens in p4_rust - Rust +

Function p4_rust::emit_tokens

source ·
pub fn emit_tokens(ast: &AST, hlir: &Hlir, settings: Settings) -> TokenStream
\ No newline at end of file diff --git a/p4_rust/fn.sanitize.html b/p4_rust/fn.sanitize.html new file mode 100644 index 00000000..92923efa --- /dev/null +++ b/p4_rust/fn.sanitize.html @@ -0,0 +1,2 @@ +sanitize in p4_rust - Rust +

Function p4_rust::sanitize

source ·
pub fn sanitize(ast: &mut AST)
\ No newline at end of file diff --git a/p4_rust/index.html b/p4_rust/index.html new file mode 100644 index 00000000..68a92c39 --- /dev/null +++ b/p4_rust/index.html @@ -0,0 +1,3 @@ +p4_rust - Rust +
\ No newline at end of file diff --git a/p4_rust/sidebar-items.js b/p4_rust/sidebar-items.js new file mode 100644 index 00000000..4e6295fc --- /dev/null +++ b/p4_rust/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["emit","emit_tokens","sanitize"],"struct":["Sanitizer","Settings"]}; \ No newline at end of file diff --git a/p4_rust/struct.Sanitizer.html b/p4_rust/struct.Sanitizer.html new file mode 100644 index 00000000..e2b48a80 --- /dev/null +++ b/p4_rust/struct.Sanitizer.html @@ -0,0 +1,12 @@ +Sanitizer in p4_rust - Rust +

Struct p4_rust::Sanitizer

source ·
pub struct Sanitizer {}

Implementations§

Trait Implementations§

source§

impl MutVisitor for Sanitizer

source§

fn struct_member(&self, m: &mut StructMember)

source§

fn header_member(&self, m: &mut HeaderMember)

source§

fn control_parameter(&self, p: &mut ControlParameter)

source§

fn action_parameter(&self, p: &mut ActionParameter)

source§

fn lvalue(&self, lv: &mut Lvalue)

§

fn constant(&self, _: &mut Constant)

§

fn header(&self, _: &mut Header)

§

fn p4struct(&self, _: &mut Struct)

§

fn typedef(&self, _: &mut Typedef)

§

fn control(&self, _: &mut Control)

§

fn parser(&self, _: &mut Parser)

§

fn package(&self, _: &mut Package)

§

fn package_instance(&self, _: &mut PackageInstance)

§

fn p4extern(&self, _: &mut Extern)

§

fn statement(&self, _: &mut Statement)

§

fn action(&self, _: &mut Action)

§

fn expression(&self, _: &mut Expression)

§

fn call(&self, _: &mut Call)

§

fn typ(&self, _: &mut Type)

§

fn binop(&self, _: &mut BinOp)

§

fn variable(&self, _: &mut Variable)

§

fn if_block(&self, _: &mut IfBlock)

§

fn else_if_block(&self, _: &mut ElseIfBlock)

§

fn transition(&self, _: &mut Transition)

§

fn select(&self, _: &mut Select)

§

fn select_element(&self, _: &mut SelectElement)

§

fn key_set_element(&self, _: &mut KeySetElement)

§

fn key_set_element_value(&self, _: &mut KeySetElementValue)

§

fn table(&self, _: &mut Table)

§

fn match_kind(&self, _: &mut MatchKind)

§

fn const_table_entry(&self, _: &mut ConstTableEntry)

§

fn action_ref(&self, _: &mut ActionRef)

§

fn state(&self, _: &mut State)

§

fn package_parameter(&self, _: &mut PackageParameter)

§

fn extern_method(&self, _: &mut ExternMethod)

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4_rust/struct.Settings.html b/p4_rust/struct.Settings.html new file mode 100644 index 00000000..b2193ca1 --- /dev/null +++ b/p4_rust/struct.Settings.html @@ -0,0 +1,15 @@ +Settings in p4_rust - Rust +

Struct p4_rust::Settings

source ·
pub struct Settings {
+    pub pipeline_name: String,
+}

Fields§

§pipeline_name: String

Name to give to the C-ABI constructor.

+

Auto Trait Implementations§

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/all.html b/p4rs/all.html new file mode 100644 index 00000000..a935bcb6 --- /dev/null +++ b/p4rs/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/p4rs/bitmath/fn.add_be.html b/p4rs/bitmath/fn.add_be.html new file mode 100644 index 00000000..7f3c939a --- /dev/null +++ b/p4rs/bitmath/fn.add_be.html @@ -0,0 +1,2 @@ +add_be in p4rs::bitmath - Rust +

Function p4rs::bitmath::add_be

source ·
pub fn add_be(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/bitmath/fn.add_generic.html b/p4rs/bitmath/fn.add_generic.html new file mode 100644 index 00000000..c505c9cd --- /dev/null +++ b/p4rs/bitmath/fn.add_generic.html @@ -0,0 +1,2 @@ +add_generic in p4rs::bitmath - Rust +

Function p4rs::bitmath::add_generic

source ·
pub fn add_generic(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/bitmath/fn.add_le.html b/p4rs/bitmath/fn.add_le.html new file mode 100644 index 00000000..3c6af663 --- /dev/null +++ b/p4rs/bitmath/fn.add_le.html @@ -0,0 +1,2 @@ +add_le in p4rs::bitmath - Rust +

Function p4rs::bitmath::add_le

source ·
pub fn add_le(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/bitmath/fn.mod_be.html b/p4rs/bitmath/fn.mod_be.html new file mode 100644 index 00000000..72a57de2 --- /dev/null +++ b/p4rs/bitmath/fn.mod_be.html @@ -0,0 +1,2 @@ +mod_be in p4rs::bitmath - Rust +

Function p4rs::bitmath::mod_be

source ·
pub fn mod_be(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/bitmath/fn.mod_le.html b/p4rs/bitmath/fn.mod_le.html new file mode 100644 index 00000000..92b56391 --- /dev/null +++ b/p4rs/bitmath/fn.mod_le.html @@ -0,0 +1,2 @@ +mod_le in p4rs::bitmath - Rust +

Function p4rs::bitmath::mod_le

source ·
pub fn mod_le(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/bitmath/index.html b/p4rs/bitmath/index.html new file mode 100644 index 00000000..d410db53 --- /dev/null +++ b/p4rs/bitmath/index.html @@ -0,0 +1,2 @@ +p4rs::bitmath - Rust +
\ No newline at end of file diff --git a/p4rs/bitmath/sidebar-items.js b/p4rs/bitmath/sidebar-items.js new file mode 100644 index 00000000..5d5ccde3 --- /dev/null +++ b/p4rs/bitmath/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["add_be","add_generic","add_le","mod_be","mod_le"]}; \ No newline at end of file diff --git a/p4rs/checksum/fn.udp6_checksum.html b/p4rs/checksum/fn.udp6_checksum.html new file mode 100644 index 00000000..7bb47de5 --- /dev/null +++ b/p4rs/checksum/fn.udp6_checksum.html @@ -0,0 +1,2 @@ +udp6_checksum in p4rs::checksum - Rust +

Function p4rs::checksum::udp6_checksum

source ·
pub fn udp6_checksum(data: &[u8]) -> u16
\ No newline at end of file diff --git a/p4rs/checksum/index.html b/p4rs/checksum/index.html new file mode 100644 index 00000000..90b80098 --- /dev/null +++ b/p4rs/checksum/index.html @@ -0,0 +1,2 @@ +p4rs::checksum - Rust +

Module p4rs::checksum

source ·

Structs§

Traits§

Functions§

\ No newline at end of file diff --git a/p4rs/checksum/sidebar-items.js b/p4rs/checksum/sidebar-items.js new file mode 100644 index 00000000..ff4d1ce8 --- /dev/null +++ b/p4rs/checksum/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["udp6_checksum"],"struct":["Csum"],"trait":["Checksum"]}; \ No newline at end of file diff --git a/p4rs/checksum/struct.Csum.html b/p4rs/checksum/struct.Csum.html new file mode 100644 index 00000000..bd4b7282 --- /dev/null +++ b/p4rs/checksum/struct.Csum.html @@ -0,0 +1,91 @@ +Csum in p4rs::checksum - Rust +

Struct p4rs::checksum::Csum

source ·
pub struct Csum(/* private fields */);

Implementations§

source§

impl Csum

source

pub fn add(&mut self, a: u8, b: u8)

source

pub fn add128(&mut self, data: [u8; 16])

source

pub fn add32(&mut self, data: [u8; 4])

source

pub fn add16(&mut self, data: [u8; 2])

source

pub fn result(&self) -> u16

Trait Implementations§

source§

impl Default for Csum

source§

fn default() -> Csum

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

Auto Trait Implementations§

§

impl RefUnwindSafe for Csum

§

impl Send for Csum

§

impl Sync for Csum

§

impl Unpin for Csum

§

impl UnwindSafe for Csum

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/checksum/trait.Checksum.html b/p4rs/checksum/trait.Checksum.html new file mode 100644 index 00000000..66dfdfad --- /dev/null +++ b/p4rs/checksum/trait.Checksum.html @@ -0,0 +1,5 @@ +Checksum in p4rs::checksum - Rust +

Trait p4rs::checksum::Checksum

source ·
pub trait Checksum {
+    // Required method
+    fn csum(&self) -> BitVec<u8, Msb0>;
+}

Required Methods§

source

fn csum(&self) -> BitVec<u8, Msb0>

Implementations on Foreign Types§

source§

impl Checksum for &BitVec<u8, Msb0>

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Checksum for BitVec<u8, Msb0>

source§

fn csum(&self) -> BitVec<u8, Msb0>

Implementors§

\ No newline at end of file diff --git a/p4rs/error/index.html b/p4rs/error/index.html new file mode 100644 index 00000000..ee92842c --- /dev/null +++ b/p4rs/error/index.html @@ -0,0 +1,2 @@ +p4rs::error - Rust +

Module p4rs::error

source ·

Structs§

\ No newline at end of file diff --git a/p4rs/error/sidebar-items.js b/p4rs/error/sidebar-items.js new file mode 100644 index 00000000..1e281ff6 --- /dev/null +++ b/p4rs/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["TryFromSliceError"]}; \ No newline at end of file diff --git a/p4rs/error/struct.TryFromSliceError.html b/p4rs/error/struct.TryFromSliceError.html new file mode 100644 index 00000000..6b40a01c --- /dev/null +++ b/p4rs/error/struct.TryFromSliceError.html @@ -0,0 +1,92 @@ +TryFromSliceError in p4rs::error - Rust +
pub struct TryFromSliceError(pub usize);

Tuple Fields§

§0: usize

Trait Implementations§

source§

impl Debug for TryFromSliceError

source§

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

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

impl Display for TryFromSliceError

source§

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

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

impl Error for TryFromSliceError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToString for T
where + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/externs/index.html b/p4rs/externs/index.html new file mode 100644 index 00000000..e22aad5e --- /dev/null +++ b/p4rs/externs/index.html @@ -0,0 +1,2 @@ +p4rs::externs - Rust +

Module p4rs::externs

source ·

Structs§

\ No newline at end of file diff --git a/p4rs/externs/sidebar-items.js b/p4rs/externs/sidebar-items.js new file mode 100644 index 00000000..42949a78 --- /dev/null +++ b/p4rs/externs/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["Checksum"]}; \ No newline at end of file diff --git a/p4rs/externs/struct.Checksum.html b/p4rs/externs/struct.Checksum.html new file mode 100644 index 00000000..42f748ea --- /dev/null +++ b/p4rs/externs/struct.Checksum.html @@ -0,0 +1,91 @@ +Checksum in p4rs::externs - Rust +

Struct p4rs::externs::Checksum

source ·
pub struct Checksum {}

Implementations§

source§

impl Checksum

source

pub fn new() -> Self

source

pub fn run(&self, elements: &[&dyn Checksum]) -> BitVec<u8, Msb0>

Trait Implementations§

source§

impl Default for Checksum

source§

fn default() -> Self

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/fn.bitvec_to_biguint.html b/p4rs/fn.bitvec_to_biguint.html new file mode 100644 index 00000000..417824d5 --- /dev/null +++ b/p4rs/fn.bitvec_to_biguint.html @@ -0,0 +1,2 @@ +bitvec_to_biguint in p4rs - Rust +

Function p4rs::bitvec_to_biguint

source ·
pub fn bitvec_to_biguint(bv: &BitVec<u8, Msb0>) -> BigUintKey
\ No newline at end of file diff --git a/p4rs/fn.bitvec_to_bitvec16.html b/p4rs/fn.bitvec_to_bitvec16.html new file mode 100644 index 00000000..931fd23e --- /dev/null +++ b/p4rs/fn.bitvec_to_bitvec16.html @@ -0,0 +1,2 @@ +bitvec_to_bitvec16 in p4rs - Rust +

Function p4rs::bitvec_to_bitvec16

source ·
pub fn bitvec_to_bitvec16(x: BitVec<u8, Msb0>) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/fn.bitvec_to_ip6addr.html b/p4rs/fn.bitvec_to_ip6addr.html new file mode 100644 index 00000000..b047b9be --- /dev/null +++ b/p4rs/fn.bitvec_to_ip6addr.html @@ -0,0 +1,2 @@ +bitvec_to_ip6addr in p4rs - Rust +

Function p4rs::bitvec_to_ip6addr

source ·
pub fn bitvec_to_ip6addr(bv: &BitVec<u8, Msb0>) -> IpAddr
\ No newline at end of file diff --git a/p4rs/fn.dump_bv.html b/p4rs/fn.dump_bv.html new file mode 100644 index 00000000..03001595 --- /dev/null +++ b/p4rs/fn.dump_bv.html @@ -0,0 +1,2 @@ +dump_bv in p4rs - Rust +

Function p4rs::dump_bv

source ·
pub fn dump_bv(x: &BitVec<u8, Msb0>) -> String
\ No newline at end of file diff --git a/p4rs/fn.extract_bit_action_parameter.html b/p4rs/fn.extract_bit_action_parameter.html new file mode 100644 index 00000000..f82cc789 --- /dev/null +++ b/p4rs/fn.extract_bit_action_parameter.html @@ -0,0 +1,6 @@ +extract_bit_action_parameter in p4rs - Rust +
pub fn extract_bit_action_parameter(
+    parameter_data: &[u8],
+    offset: usize,
+    size: usize
+) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/fn.extract_bool_action_parameter.html b/p4rs/fn.extract_bool_action_parameter.html new file mode 100644 index 00000000..a67d0e29 --- /dev/null +++ b/p4rs/fn.extract_bool_action_parameter.html @@ -0,0 +1,5 @@ +extract_bool_action_parameter in p4rs - Rust +
pub fn extract_bool_action_parameter(
+    parameter_data: &[u8],
+    offset: usize
+) -> bool
\ No newline at end of file diff --git a/p4rs/fn.extract_exact_key.html b/p4rs/fn.extract_exact_key.html new file mode 100644 index 00000000..87d1f894 --- /dev/null +++ b/p4rs/fn.extract_exact_key.html @@ -0,0 +1,2 @@ +extract_exact_key in p4rs - Rust +

Function p4rs::extract_exact_key

source ·
pub fn extract_exact_key(keyset_data: &[u8], offset: usize, len: usize) -> Key
\ No newline at end of file diff --git a/p4rs/fn.extract_lpm_key.html b/p4rs/fn.extract_lpm_key.html new file mode 100644 index 00000000..54385837 --- /dev/null +++ b/p4rs/fn.extract_lpm_key.html @@ -0,0 +1,2 @@ +extract_lpm_key in p4rs - Rust +

Function p4rs::extract_lpm_key

source ·
pub fn extract_lpm_key(keyset_data: &[u8], offset: usize, _len: usize) -> Key
\ No newline at end of file diff --git a/p4rs/fn.extract_range_key.html b/p4rs/fn.extract_range_key.html new file mode 100644 index 00000000..a4fb033f --- /dev/null +++ b/p4rs/fn.extract_range_key.html @@ -0,0 +1,2 @@ +extract_range_key in p4rs - Rust +

Function p4rs::extract_range_key

source ·
pub fn extract_range_key(keyset_data: &[u8], offset: usize, len: usize) -> Key
\ No newline at end of file diff --git a/p4rs/fn.extract_ternary_key.html b/p4rs/fn.extract_ternary_key.html new file mode 100644 index 00000000..29967c42 --- /dev/null +++ b/p4rs/fn.extract_ternary_key.html @@ -0,0 +1,7 @@ +extract_ternary_key in p4rs - Rust +

Function p4rs::extract_ternary_key

source ·
pub fn extract_ternary_key(keyset_data: &[u8], offset: usize, len: usize) -> Key
Expand description

Extract a ternary key from the provided keyset data. Ternary keys come in +two parts. The first part is a leading bit that indicates whether we care +about the value. If that leading bit is non-zero, the trailing bits of the +key are interpreted as a binary value. If the leading bit is zero, the +trailing bits are ignored and a Ternary::DontCare key is returned.

+
\ No newline at end of file diff --git a/p4rs/fn.int_to_bitvec.html b/p4rs/fn.int_to_bitvec.html new file mode 100644 index 00000000..6e5d3626 --- /dev/null +++ b/p4rs/fn.int_to_bitvec.html @@ -0,0 +1,2 @@ +int_to_bitvec in p4rs - Rust +

Function p4rs::int_to_bitvec

source ·
pub fn int_to_bitvec(x: i128) -> BitVec<u8, Msb0>
\ No newline at end of file diff --git a/p4rs/index.html b/p4rs/index.html new file mode 100644 index 00000000..f759f475 --- /dev/null +++ b/p4rs/index.html @@ -0,0 +1,62 @@ +p4rs - Rust +

Crate p4rs

source ·
Expand description

This is the runtime support create for x4c generated programs.

+

The main abstraction in this crate is the Pipeline trait. Rust code that +is generated by x4c implements this trait. A main_pipeline struct is +exported by the generated code that implements Pipeline. Users can wrap +the main_pipeline object in harness code to provide higher level +interfaces for table manipulation and packet i/o.

+ +
use p4rs::{ packet_in, packet_out, Pipeline };
+use std::net::Ipv6Addr;
+
+struct Handler {
+    pipe: Box<dyn Pipeline>
+}
+
+impl Handler {
+    /// Create a new pipeline handler.
+    fn new(pipe: Box<dyn Pipeline>) -> Self {
+        Self{ pipe }
+    }
+
+    /// Handle a packet from the specified port. If the pipeline produces
+    /// an output result, send the processed packet to the output port
+    /// returned by the pipeline.
+    fn handle_packet(&mut self, port: u16, pkt: &[u8]) {
+
+        let mut input = packet_in::new(pkt);
+
+        let output =  self.pipe.process_packet(port, &mut input);
+        for (out_pkt, out_port) in &output {
+            let mut out = out_pkt.header_data.clone();
+            out.extend_from_slice(out_pkt.payload_data);
+            self.send_packet(*out_port, &out);
+        }
+
+    }
+
+    /// Add a routing table entry. Packets for the provided destination will
+    /// be sent out the specified port.
+    fn add_router_entry(&mut self, dest: Ipv6Addr, port: u16) {
+        self.pipe.add_table_entry(
+            "ingress.router.ipv6_routes", // qualified name of the table
+            "forward_out_port",           // action to invoke on a hit
+            &dest.octets(),
+            &port.to_le_bytes(),
+            0,
+        );
+    }
+
+    /// Send a packet out the specified port.
+    fn send_packet(&self, port: u16, pkt: &[u8]) {
+        // send the packet ...
+    }
+}
+

Re-exports§

Modules§

Structs§

  • Every packet that goes through a P4 pipeline is represented as a packet_in +instance. packet_in objects wrap an underlying mutable data reference that +is ultimately rooted in a memory mapped region containing a ring of packets.

Traits§

Functions§

\ No newline at end of file diff --git a/p4rs/sidebar-items.js b/p4rs/sidebar-items.js new file mode 100644 index 00000000..484fff87 --- /dev/null +++ b/p4rs/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["bitvec_to_biguint","bitvec_to_bitvec16","bitvec_to_ip6addr","dump_bv","extract_bit_action_parameter","extract_bool_action_parameter","extract_exact_key","extract_lpm_key","extract_range_key","extract_ternary_key","int_to_bitvec"],"mod":["bitmath","checksum","error","externs","table"],"struct":["AlignedU128","Bit","TableEntry","packet_in","packet_out"],"trait":["Header","Pipeline"]}; \ No newline at end of file diff --git a/p4rs/struct.AlignedU128.html b/p4rs/struct.AlignedU128.html new file mode 100644 index 00000000..72d8bca4 --- /dev/null +++ b/p4rs/struct.AlignedU128.html @@ -0,0 +1,91 @@ +AlignedU128 in p4rs - Rust +

Struct p4rs::AlignedU128

source ·
#[repr(C, align(16))]
pub struct AlignedU128(pub u128);

Tuple Fields§

§0: u128

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/struct.Bit.html b/p4rs/struct.Bit.html new file mode 100644 index 00000000..4f903c73 --- /dev/null +++ b/p4rs/struct.Bit.html @@ -0,0 +1,95 @@ +Bit in p4rs - Rust +

Struct p4rs::Bit

source ·
pub struct Bit<'a, const N: usize>(pub &'a [u8]);

Tuple Fields§

§0: &'a [u8]

Implementations§

source§

impl<'a, const N: usize> Bit<'a, N>

source

pub fn new(data: &'a [u8]) -> Result<Self, TryFromSliceError>

Trait Implementations§

source§

impl<'a, const N: usize> Debug for Bit<'a, N>

source§

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

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

impl<'a> From<Bit<'a, 16>> for u16

source§

fn from(b: Bit<'a, 16>) -> u16

Converts to this type from the input type.
source§

impl<'a> Hash for Bit<'a, 8>

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<'a, const N: usize> LowerHex for Bit<'a, N>

source§

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

Formats the value using the given formatter.
source§

impl<'a> PartialEq for Bit<'a, 8>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<'a> Eq for Bit<'a, 8>

Auto Trait Implementations§

§

impl<'a, const N: usize> RefUnwindSafe for Bit<'a, N>

§

impl<'a, const N: usize> Send for Bit<'a, N>

§

impl<'a, const N: usize> Sync for Bit<'a, N>

§

impl<'a, const N: usize> Unpin for Bit<'a, N>

§

impl<'a, const N: usize> UnwindSafe for Bit<'a, N>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/struct.TableEntry.html b/p4rs/struct.TableEntry.html new file mode 100644 index 00000000..0e7ffde0 --- /dev/null +++ b/p4rs/struct.TableEntry.html @@ -0,0 +1,98 @@ +TableEntry in p4rs - Rust +

Struct p4rs::TableEntry

source ·
pub struct TableEntry {
+    pub action_id: String,
+    pub keyset_data: Vec<u8>,
+    pub parameter_data: Vec<u8>,
+}

Fields§

§action_id: String§keyset_data: Vec<u8>§parameter_data: Vec<u8>

Trait Implementations§

source§

impl Debug for TableEntry

source§

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

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

impl<'de> Deserialize<'de> for TableEntry

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Serialize for TableEntry

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
source§

impl<T> DeserializeOwned for T
where + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/p4rs/struct.packet_in.html b/p4rs/struct.packet_in.html new file mode 100644 index 00000000..f4d11cb5 --- /dev/null +++ b/p4rs/struct.packet_in.html @@ -0,0 +1,101 @@ +packet_in in p4rs - Rust +

Struct p4rs::packet_in

source ·
pub struct packet_in<'a> {
+    pub data: &'a [u8],
+    pub index: usize,
+}
Expand description

Every packet that goes through a P4 pipeline is represented as a packet_in +instance. packet_in objects wrap an underlying mutable data reference that +is ultimately rooted in a memory mapped region containing a ring of packets.

+

Fields§

§data: &'a [u8]

The underlying data. Owned by an external, memory-mapped packet ring.

+
§index: usize

Extraction index. Everything before index has been extracted already. +Only data after index is eligble for extraction. Extraction is always +for contiguous segments of the underlying packet ring data.

+

Implementations§

source§

impl<'a> packet_in<'a>

source

pub fn new(data: &'a [u8]) -> Self

source

pub fn extract<H: Header>(&mut self, h: &mut H)

source

pub fn extract_new<H: Header>(&mut self) -> Result<H, TryFromSliceError>

Trait Implementations§

source§

impl<'a> Debug for packet_in<'a>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for packet_in<'a>

§

impl<'a> Send for packet_in<'a>

§

impl<'a> Sync for packet_in<'a>

§

impl<'a> Unpin for packet_in<'a>

§

impl<'a> UnwindSafe for packet_in<'a>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/struct.packet_out.html b/p4rs/struct.packet_out.html new file mode 100644 index 00000000..13d13711 --- /dev/null +++ b/p4rs/struct.packet_out.html @@ -0,0 +1,94 @@ +packet_out in p4rs - Rust +

Struct p4rs::packet_out

source ·
pub struct packet_out<'a> {
+    pub header_data: Vec<u8>,
+    pub payload_data: &'a [u8],
+}

Fields§

§header_data: Vec<u8>§payload_data: &'a [u8]

Trait Implementations§

source§

impl<'a> Debug for packet_out<'a>

source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for packet_out<'a>

§

impl<'a> Send for packet_out<'a>

§

impl<'a> Sync for packet_out<'a>

§

impl<'a> Unpin for packet_out<'a>

§

impl<'a> UnwindSafe for packet_out<'a>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/table/enum.Key.html b/p4rs/table/enum.Key.html new file mode 100644 index 00000000..59176279 --- /dev/null +++ b/p4rs/table/enum.Key.html @@ -0,0 +1,104 @@ +Key in p4rs::table - Rust +

Enum p4rs::table::Key

source ·
pub enum Key {
+    Exact(BigUintKey),
+    Range(BigUintKey, BigUintKey),
+    Ternary(Ternary),
+    Lpm(Prefix),
+}

Variants§

Implementations§

source§

impl Key

source

pub fn to_bytes(&self) -> Vec<u8>

Trait Implementations§

source§

impl Clone for Key

source§

fn clone(&self) -> Key

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 Debug for Key

source§

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

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

impl Default for Key

source§

fn default() -> Self

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

impl<'de> Deserialize<'de> for Key

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for Key

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Key

source§

fn eq(&self, other: &Key) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Serialize for Key

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Eq for Key

source§

impl StructuralPartialEq for Key

Auto Trait Implementations§

§

impl RefUnwindSafe for Key

§

impl Send for Key

§

impl Sync for Key

§

impl Unpin for Key

§

impl UnwindSafe for Key

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
source§

impl<T> DeserializeOwned for T
where + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/p4rs/table/enum.Ternary.html b/p4rs/table/enum.Ternary.html new file mode 100644 index 00000000..ed339214 --- /dev/null +++ b/p4rs/table/enum.Ternary.html @@ -0,0 +1,103 @@ +Ternary in p4rs::table - Rust +

Enum p4rs::table::Ternary

source ·
pub enum Ternary {
+    DontCare,
+    Value(BigUintKey),
+    Masked(BigUint, BigUint, usize),
+}

Variants§

§

DontCare

§

Value(BigUintKey)

§

Masked(BigUint, BigUint, usize)

Trait Implementations§

source§

impl Clone for Ternary

source§

fn clone(&self) -> Ternary

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 Debug for Ternary

source§

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

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

impl Default for Ternary

source§

fn default() -> Self

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

impl<'de> Deserialize<'de> for Ternary

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for Ternary

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Ternary

source§

fn eq(&self, other: &Ternary) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Serialize for Ternary

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Eq for Ternary

source§

impl StructuralPartialEq for Ternary

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
source§

impl<T> DeserializeOwned for T
where + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/p4rs/table/fn.key_matches.html b/p4rs/table/fn.key_matches.html new file mode 100644 index 00000000..61f93052 --- /dev/null +++ b/p4rs/table/fn.key_matches.html @@ -0,0 +1,2 @@ +key_matches in p4rs::table - Rust +

Function p4rs::table::key_matches

source ·
pub fn key_matches(selector: &BigUint, key: &Key) -> bool
\ No newline at end of file diff --git a/p4rs/table/fn.keyset_matches.html b/p4rs/table/fn.keyset_matches.html new file mode 100644 index 00000000..edeaf9c2 --- /dev/null +++ b/p4rs/table/fn.keyset_matches.html @@ -0,0 +1,5 @@ +keyset_matches in p4rs::table - Rust +

Function p4rs::table::keyset_matches

source ·
pub fn keyset_matches<const D: usize>(
+    selector: &[BigUint; D],
+    key: &[Key; D]
+) -> bool
\ No newline at end of file diff --git a/p4rs/table/fn.prune_entries_by_lpm.html b/p4rs/table/fn.prune_entries_by_lpm.html new file mode 100644 index 00000000..34e3894d --- /dev/null +++ b/p4rs/table/fn.prune_entries_by_lpm.html @@ -0,0 +1,5 @@ +prune_entries_by_lpm in p4rs::table - Rust +
pub fn prune_entries_by_lpm<const D: usize, A: Clone>(
+    d: usize,
+    entries: &Vec<TableEntry<D, A>>
+) -> Vec<TableEntry<D, A>>
\ No newline at end of file diff --git a/p4rs/table/fn.sort_entries.html b/p4rs/table/fn.sort_entries.html new file mode 100644 index 00000000..5150a96d --- /dev/null +++ b/p4rs/table/fn.sort_entries.html @@ -0,0 +1,4 @@ +sort_entries in p4rs::table - Rust +

Function p4rs::table::sort_entries

source ·
pub fn sort_entries<const D: usize, A: Clone>(
+    entries: Vec<TableEntry<D, A>>
+) -> Vec<TableEntry<D, A>>
\ No newline at end of file diff --git a/p4rs/table/fn.sort_entries_by_priority.html b/p4rs/table/fn.sort_entries_by_priority.html new file mode 100644 index 00000000..b1422461 --- /dev/null +++ b/p4rs/table/fn.sort_entries_by_priority.html @@ -0,0 +1,4 @@ +sort_entries_by_priority in p4rs::table - Rust +
pub fn sort_entries_by_priority<const D: usize, A: Clone>(
+    entries: &mut [TableEntry<D, A>]
+)
\ No newline at end of file diff --git a/p4rs/table/index.html b/p4rs/table/index.html new file mode 100644 index 00000000..6eb52eb8 --- /dev/null +++ b/p4rs/table/index.html @@ -0,0 +1,2 @@ +p4rs::table - Rust +
\ No newline at end of file diff --git a/p4rs/table/sidebar-items.js b/p4rs/table/sidebar-items.js new file mode 100644 index 00000000..178841f2 --- /dev/null +++ b/p4rs/table/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Key","Ternary"],"fn":["key_matches","keyset_matches","prune_entries_by_lpm","sort_entries","sort_entries_by_priority"],"struct":["BigUintKey","Prefix","Table","TableEntry"]}; \ No newline at end of file diff --git a/p4rs/table/struct.BigUintKey.html b/p4rs/table/struct.BigUintKey.html new file mode 100644 index 00000000..5ffac74e --- /dev/null +++ b/p4rs/table/struct.BigUintKey.html @@ -0,0 +1,102 @@ +BigUintKey in p4rs::table - Rust +

Struct p4rs::table::BigUintKey

source ·
pub struct BigUintKey {
+    pub value: BigUint,
+    pub width: usize,
+}

Fields§

§value: BigUint§width: usize

Trait Implementations§

source§

impl Clone for BigUintKey

source§

fn clone(&self) -> BigUintKey

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 Debug for BigUintKey

source§

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

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

impl<'de> Deserialize<'de> for BigUintKey

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for BigUintKey

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for BigUintKey

source§

fn eq(&self, other: &BigUintKey) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Serialize for BigUintKey

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Eq for BigUintKey

source§

impl StructuralPartialEq for BigUintKey

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
source§

impl<T> DeserializeOwned for T
where + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/p4rs/table/struct.Prefix.html b/p4rs/table/struct.Prefix.html new file mode 100644 index 00000000..b5bbb80a --- /dev/null +++ b/p4rs/table/struct.Prefix.html @@ -0,0 +1,102 @@ +Prefix in p4rs::table - Rust +

Struct p4rs::table::Prefix

source ·
pub struct Prefix {
+    pub addr: IpAddr,
+    pub len: u8,
+}

Fields§

§addr: IpAddr§len: u8

Trait Implementations§

source§

impl Clone for Prefix

source§

fn clone(&self) -> Prefix

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 Debug for Prefix

source§

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

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

impl<'de> Deserialize<'de> for Prefix

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl Hash for Prefix

source§

fn hash<__H: Hasher>(&self, state: &mut __H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl PartialEq for Prefix

source§

fn eq(&self, other: &Prefix) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Serialize for Prefix

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl Eq for Prefix

source§

impl StructuralPartialEq for Prefix

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
source§

impl<T> DeserializeOwned for T
where + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/p4rs/table/struct.Table.html b/p4rs/table/struct.Table.html new file mode 100644 index 00000000..8d550b95 --- /dev/null +++ b/p4rs/table/struct.Table.html @@ -0,0 +1,98 @@ +Table in p4rs::table - Rust +

Struct p4rs::table::Table

source ·
pub struct Table<const D: usize, A: Clone> {
+    pub entries: HashSet<TableEntry<D, A>>,
+}

Fields§

§entries: HashSet<TableEntry<D, A>>

Implementations§

source§

impl<const D: usize, A: Clone> Table<D, A>

source

pub fn new() -> Self

source

pub fn match_selector(&self, keyset: &[BigUint; D]) -> Vec<TableEntry<D, A>>

source

pub fn dump(&self) -> String

Trait Implementations§

source§

impl<const D: usize, A: Clone> Default for Table<D, A>

source§

fn default() -> Self

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

Auto Trait Implementations§

§

impl<const D: usize, A> RefUnwindSafe for Table<D, A>
where + A: RefUnwindSafe,

§

impl<const D: usize, A> Send for Table<D, A>
where + A: Send,

§

impl<const D: usize, A> Sync for Table<D, A>
where + A: Sync,

§

impl<const D: usize, A> Unpin for Table<D, A>
where + A: Unpin,

§

impl<const D: usize, A> UnwindSafe for Table<D, A>
where + A: 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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/table/struct.TableEntry.html b/p4rs/table/struct.TableEntry.html new file mode 100644 index 00000000..ad0a7cb0 --- /dev/null +++ b/p4rs/table/struct.TableEntry.html @@ -0,0 +1,108 @@ +TableEntry in p4rs::table - Rust +

Struct p4rs::table::TableEntry

source ·
pub struct TableEntry<const D: usize, A: Clone> {
+    pub key: [Key; D],
+    pub action: A,
+    pub priority: u32,
+    pub name: String,
+    pub action_id: String,
+    pub parameter_data: Vec<u8>,
+}

Fields§

§key: [Key; D]§action: A§priority: u32§name: String§action_id: String§parameter_data: Vec<u8>

Trait Implementations§

source§

impl<const D: usize, A: Clone + Clone> Clone for TableEntry<D, A>

source§

fn clone(&self) -> TableEntry<D, A>

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<const D: usize, A: Clone> Debug for TableEntry<D, A>

source§

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

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

impl<const D: usize, A: Clone> Hash for TableEntry<D, A>

source§

fn hash<H: Hasher>(&self, state: &mut H)

Feeds this value into the given Hasher. Read more
1.3.0 · source§

fn hash_slice<H>(data: &[Self], state: &mut H)
where + H: Hasher, + Self: Sized,

Feeds a slice of this type into the given Hasher. Read more
source§

impl<const D: usize, A: Clone> PartialEq for TableEntry<D, A>

source§

fn eq(&self, other: &Self) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

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

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<const D: usize, A: Clone> Eq for TableEntry<D, A>

Auto Trait Implementations§

§

impl<const D: usize, A> RefUnwindSafe for TableEntry<D, A>
where + A: RefUnwindSafe,

§

impl<const D: usize, A> Send for TableEntry<D, A>
where + A: Send,

§

impl<const D: usize, A> Sync for TableEntry<D, A>
where + A: Sync,

§

impl<const D: usize, A> Unpin for TableEntry<D, A>
where + A: Unpin,

§

impl<const D: usize, A> UnwindSafe for TableEntry<D, A>
where + A: 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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/p4rs/trait.Header.html b/p4rs/trait.Header.html new file mode 100644 index 00000000..e70ce755 --- /dev/null +++ b/p4rs/trait.Header.html @@ -0,0 +1,12 @@ +Header in p4rs - Rust +

Trait p4rs::Header

source ·
pub trait Header {
+    // Required methods
+    fn new() -> Self;
+    fn size() -> usize;
+    fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>;
+    fn set_valid(&mut self);
+    fn set_invalid(&mut self);
+    fn is_valid(&self) -> bool;
+    fn to_bitvec(&self) -> BitVec<u8, Msb0>;
+}
Expand description

A fixed length header trait.

+

Required Methods§

source

fn new() -> Self

source

fn size() -> usize

source

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source

fn set_valid(&mut self)

source

fn set_invalid(&mut self)

source

fn is_valid(&self) -> bool

source

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Object Safety§

This trait is not object safe.

Implementors§

\ No newline at end of file diff --git a/p4rs/trait.Pipeline.html b/p4rs/trait.Pipeline.html new file mode 100644 index 00000000..eac050d0 --- /dev/null +++ b/p4rs/trait.Pipeline.html @@ -0,0 +1,38 @@ +Pipeline in p4rs - Rust +

Trait p4rs::Pipeline

source ·
pub trait Pipeline: Send {
+    // Required methods
+    fn process_packet<'a>(
+        &mut self,
+        port: u16,
+        pkt: &mut packet_in<'a>
+    ) -> Vec<(packet_out<'a>, u16)>;
+    fn add_table_entry(
+        &mut self,
+        table_id: &str,
+        action_id: &str,
+        keyset_data: &[u8],
+        parameter_data: &[u8],
+        priority: u32
+    );
+    fn remove_table_entry(&mut self, table_id: &str, keyset_data: &[u8]);
+    fn get_table_entries(&self, table_id: &str) -> Option<Vec<TableEntry>>;
+    fn get_table_ids(&self) -> Vec<&str>;
+}

Required Methods§

source

fn process_packet<'a>( + &mut self, + port: u16, + pkt: &mut packet_in<'a> +) -> Vec<(packet_out<'a>, u16)>

Process an input packet and produce a set of output packets. Normally +there will be a single output packet. However, if the pipeline sets +egress_metadata_t.broadcast there may be multiple output packets.

+
source

fn add_table_entry( + &mut self, + table_id: &str, + action_id: &str, + keyset_data: &[u8], + parameter_data: &[u8], + priority: u32 +)

Add an entry to a table identified by table_id.

+
source

fn remove_table_entry(&mut self, table_id: &str, keyset_data: &[u8])

Remove an entry from a table identified by table_id.

+
source

fn get_table_entries(&self, table_id: &str) -> Option<Vec<TableEntry>>

Get all the entries in a table.

+
source

fn get_table_ids(&self) -> Vec<&str>

Get a list of table ids

+

Implementors§

\ No newline at end of file diff --git a/search-index.js b/search-index.js new file mode 100644 index 00000000..9d860a8d --- /dev/null +++ b/search-index.js @@ -0,0 +1,15 @@ +var searchIndex = new Map(JSON.parse('[\ +["hello_world",{"doc":"","t":"HNNNNNNNNNNNNONNNNNNNNNNNNNOOONNNNOHFOOFNNNNNNNNNNNNFOHHHFHONNNNNNNHFNNOHHOONNONNNNNNNNCONNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNQQQQQQQQQQQQQ","n":["_hello_pipeline_create","add_ingress_tbl_entry","add_table_entry","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","csum","default","default","default","default","drop","drop","dst","dump","dump","dump","dump","egress","egress_apply","egress_metadata_t","ether_type","ethernet","ethernet_h","fmt","fmt","fmt","fmt","from","from","from","from","from","get_ingress_tbl_entries","get_table_entries","get_table_ids","headers_t","ingress","ingress_action_drop","ingress_action_forward","ingress_apply","ingress_metadata_t","ingress_tbl","ingress_tbl","into","into","into","into","into","isValid","is_valid","main","main_pipeline","new","new","parse","parse_finish","parse_start","port","port","process_packet","process_packet_headers","radix","remove_ingress_tbl_entry","remove_table_entry","set","setInvalid","setValid","set_invalid","set_valid","size","softnpu_provider","src","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","valid","valid_header_size","valid_header_size","valid_header_size","vzip","vzip","vzip","vzip","vzip","action","control_apply","control_table_hit","control_table_miss","egress_accepted","egress_dropped","egress_table_hit","egress_table_miss","ingress_accepted","ingress_dropped","parser_accepted","parser_dropped","parser_transition"],"q":[[0,"hello_world"],[121,"hello_world::softnpu_provider"],[134,"p4rs"],[135,"bitvec::order"],[136,"bitvec::vec"],[137,"alloc::string"],[138,"core::fmt"],[139,"core::fmt"],[140,"core::option"],[141,"core::ops::function"],[142,"alloc::sync"],[143,"p4rs::table"],[144,"anyhow"],[145,"core::result"],[146,"p4rs"],[147,"core::any"]],"d":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,3,3,3,9,10,11,12,3,9,10,11,12,11,9,10,11,12,9,10,11,12,10,9,10,11,12,11,12,10,9,10,11,12,3,0,0,10,9,0,9,10,11,12,3,9,10,11,12,3,3,3,0,3,0,0,0,0,0,3,3,9,10,11,12,10,10,0,0,3,10,3,0,0,11,12,3,3,3,3,3,10,10,10,10,10,10,0,10,9,10,11,12,9,10,11,12,3,9,10,11,12,3,9,10,11,12,3,9,10,11,12,10,9,11,12,3,9,10,11,12,0,0,0,0,0,0,0,0,0,0,0,0,0],"f":"{bd}{{fh{l{j}}{l{j}}n}A`}{{fhh{l{j}}{l{j}}n}A`}{ce{}{}}000000000`{AbAb}{AdAd}{AfAf}{AhAh}{{ce}A`{}{}}000{Ad{{Al{jAj}}}}{{}Ab}{{}Ad}{{}Af}{{}Ah}```{AbAn}{AdAn}{AfAn}{AhAn}`{{AbAhAf}A`}````{{AbB`}Bb}{{AdB`}Bb}{{AfB`}Bb}{{AhB`}Bb}{cc{}}0000{f{{Bf{Bd}}}}{{fh}{{Bh{{Bf{Bd}}}}}}{f{{Bf{h}}}}``8{{AbAhAf{Al{jAj}}}A`}{{AbAhAf{Bn{{Bl{Bj}}}}}A`}`{{}{{Bn{{Bl{Bj}}}}}}`{ce{}{}}0000{AdC`}0{{}{{Cd{A`Cb}}}}`{bf}{{}Ad}`{{CfAbAh}C`}0``{{fbCf}{{Bf{{Cj{Chb}}}}}}{{fbCf}{{Bf{{Cj{Abb}}}}}}`{{f{l{j}}}A`}{{fh{l{j}}}A`}{{Ad{l{j}}}{{Cd{A`Cl}}}}{AdA`}000{{}Cn}``{Ab{{Al{jAj}}}}{Ad{{Al{jAj}}}}{Af{{Al{jAj}}}}{Ah{{Al{jAj}}}}{ce{}{}}000{c{{Cd{e}}}{}{}}000000000{cD`{}}0000`{AbCn}{AfCn}{AhCn}55555`````````````","c":[],"p":[[1,"u16"],[10,"Pipeline",134],[5,"main_pipeline",0],[1,"str"],[1,"u8"],[1,"slice"],[1,"u32"],[1,"unit"],[5,"headers_t",0],[5,"ethernet_h",0],[5,"egress_metadata_t",0],[5,"ingress_metadata_t",0],[5,"Msb0",135],[5,"BitVec",136],[5,"String",137],[5,"Formatter",138],[8,"Result",138],[5,"TableEntry",134],[5,"Vec",139],[6,"Option",140],[10,"Fn",141],[5,"Arc",142],[5,"Table",143],[1,"bool"],[5,"Error",144],[6,"Result",145],[5,"packet_in",134],[5,"packet_out",134],[1,"tuple"],[5,"TryFromSliceError",146],[1,"usize"],[5,"TypeId",147]],"b":[]}],\ +["p4",{"doc":"","t":"CCCCCCCCFFPPFPFPPGPPPPPPPFPPFFPFPFPGPGPFPPPPFPGFPPFPPFPFPPPFPPPPPFGPPPPPPFPPPGPPKKFPPFFFPFPPPPFPFPPFPPGFPFPFPPFPPGPGFPPGPFPKKPPNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNOOOONNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNOONNNNNNNNOOONNNONOOOOONNNNONNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNOOONONNNNNNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNOOOOOOOOOONNNNONNNNOOONNNNNNNNNONNNNNNNNOOOONNNNONNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOOOOONNNNOONNNNOFFPFFPFFPGFFPHNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONONNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNGPPFFPFFOONNNNNNNNNNOOONNNNNNNNNNNNNNNNNNNNNNNOOOOOOOOOONNNNNNNNNNNNNNNNNNNNFFNNNNNOONNNONNONNNNNNNNPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPGPFPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPFPPPPPNNNNNNNNNNNOONNONNNNNNNNNNNNOOONNONNNNNNNNNNNNNFFFFFFFFFFFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFFNNNNNNONNNNONNOHNNNNNNH","n":["ast","check","error","hlir","lexer","parser","preprocessor","util","AST","Action","Action","Action","ActionParameter","ActionParameter","ActionRef","Add","Assignment","BinOp","Binary","Bit","BitAnd","BitLit","BitOr","Bool","BoolLit","Call","Call","Call","ConstTableEntry","Constant","Constant","Control","ControlMember","ControlParameter","ControlTable","DeclarationInfo","Default","Direction","DontCare","ElseIfBlock","Empty","Eq","Error","Exact","Expression","Expression","ExpressionKind","Extern","Extern","ExternFunction","ExternMethod","Geq","Gt","Header","Header","HeaderMember","HeaderMember","HeaderMethod","If","IfBlock","In","InOut","Index","Int","IntegerLit","KeySetElement","KeySetElementValue","Leq","List","List","Local","LongestPrefixMatch","Lt","Lvalue","Lvalue","Mask","Masked","MatchKind","Method","Mod","MutVisitor","MutVisitorMut","NameInfo","NotEq","Out","Package","PackageInstance","PackageParameter","Parameter","Parser","Range","Ranged","Reference","Return","Select","Select","SelectElement","SignedLit","Slice","State","State","State","Statement","StatementBlock","String","Struct","Struct","StructMember","StructMember","Subtract","Table","Table","Ternary","Transition","Transition","Type","Typedef","Unspecified","UserDefined","UserDefinedType","Varbit","Variable","Variable","Visitor","VisitorMut","Void","Xor","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","accept_mut","action","action","action","action","action","action_parameter","action_parameter","action_parameter","action_parameter","action_ref","action_ref","action_ref","action_ref","actions","actions","apply","args","binop","binop","binop","binop","block","block","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","call","call","call","call","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","cmp","const_entries","const_table_entry","const_table_entry","const_table_entry","const_table_entry","constant","constant","constant","constant","constants","constants","control","control","control","control","control_parameter","control_parameter","control_parameter","control_parameter","controls","decl","decl_only","default","default","default","default_action","degree","dir_token","direction","direction","elements","else_block","else_if_block","else_if_block","else_if_block","else_if_block","else_ifs","english_verb","eq","eq","eq","eq","eq","eq","eq","expression","expression","expression","expression","extern_method","extern_method","extern_method","extern_method","externs","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","get_action","get_control","get_extern","get_header","get_method","get_parameter","get_parser","get_start_state","get_struct","get_table","get_user_defined_type","hash","hash","header","header","header","header","header_member","header_member","header_member","header_member","headers","if_block","if_block","if_block","if_block","initializer","initializer","instance_type","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","is_type_parameter","is_type_parameter","key","key_set_element","key_set_element","key_set_element","key_set_element","key_set_element_value","key_set_element_value","key_set_element_value","key_set_element_value","keyset","keyset","kind","leaf","lval","lvalue","lvalue","lvalue","lvalue","match_kind","match_kind","match_kind","match_kind","members","members","methods","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","mut_accept_mut","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name","name_token","name_token","names","names","names","names","names","names","new","new","new","new","new","new","new","new","new","new","new","new","p4extern","p4extern","p4extern","p4extern","p4struct","p4struct","p4struct","p4struct","package","package","package","package","package_instance","package_instance","package_instance","package_instance","package_instance","package_parameter","package_parameter","package_parameter","package_parameter","packages","parameters","parameters","parameters","parameters","parameters","parameters","parameters","parameters","parameters","parser","parser","parser","parser","parsers","partial_cmp","parts","pop_left","pop_right","predicate","predicate","return_type","root","select","select","select","select","select_element","select_element","select_element","select_element","size","state","state","state","state","statement","statement","statement","statement","statement_block","statements","statements","states","struct_member","struct_member","struct_member","struct_member","structs","table","table","table","table","tables","tables","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_string","token","token","token","token","token","token","token","token","token","token","token","transition","transition","transition","transition","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","ty","ty","ty","ty","ty","ty","ty","ty","ty_token","ty_token","typ","typ","typ","typ","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_name","type_parameters","type_parameters","type_parameters","type_parameters","type_parameters","typedef","typedef","typedef","typedef","typedefs","value","variable","variable","variable","variable","variables","ApplyCallChecker","ControlChecker","Deprecation","Diagnostic","Diagnostics","Error","ExpressionTypeChecker","HeaderChecker","Info","Level","ParserChecker","StructChecker","Warning","all","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","call","check","check","check","check","check_actions","check_apply","check_apply_ctl_apply","check_apply_table_apply","check_constant","check_control","check_expression","check_params","check_parser","check_statement_block","check_table","check_table_action_reference","check_tables","check_variables","clone","clone","clone_into","clone_into","default","ensure_transition","eq","errors","extend","fmt","fmt","fmt","from","from","from","from","from","from","from","from","from","into","into","into","into","into","into","into","into","into","level","lvalues","message","new","push","run","start_state","to_owned","to_owned","token","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","Error","Lexer","Parser","ParserError","PreprocessorError","Semantic","SemanticError","TokenError","at","at","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","col","file","file","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","into","into","into","into","into","len","line","line","message","message","message","source","source","source","source","to_string","to_string","to_string","to_string","to_string","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","Hlir","HlirGenerator","borrow","borrow","borrow_mut","borrow_mut","default","diags","expression_types","fmt","from","from","hlir","into","into","lvalue_decls","new","run","try_from","try_from","try_into","try_into","type_id","type_id","Action","Actions","And","AngleClose","AngleOpen","Apply","Backslash","Bang","Bit","BitLiteral","Bool","Carat","Colon","Comma","Const","Control","CurlyClose","CurlyOpen","DefaultAction","Dot","DoubleEquals","Else","Entries","Eof","Equals","Error","Exact","Extern","FalseLiteral","Forwardslash","GreaterThanEquals","Header","Identifier","If","In","InOut","Int","IntLiteral","Key","Kind","LessThanEquals","Lexer","LogicalAnd","Lpm","Mask","Minus","Mod","NotEquals","Out","Package","ParenClose","ParenOpen","Parser","Pipe","Plus","PoundDefine","PoundInclude","Range","Return","Select","Semicolon","Shl","SignedLiteral","Size","SquareClose","SquareOpen","State","String","StringLiteral","Struct","Table","Ternary","Tilde","Token","Transition","TrueLiteral","Typedef","Underscore","Varbit","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","check_end_of_line","clone","clone","clone_into","clone_into","col","col","eq","eq","file","fmt","fmt","fmt","fmt","from","from","from","hash","hash","into","into","into","kind","line","line","new","next","show_tokens","to_owned","to_owned","to_string","to_string","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","ActionParser","ControlParser","ExpressionParser","GlobalParser","IfElseParser","Parser","ParserParser","SelectParser","StateParser","StatementParser","TableParser","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","from","from","from","from","from","from","from","from","from","from","from","handle_const_decl","handle_control","handle_extern","handle_header_decl","handle_package","handle_package_instance","handle_parser","handle_struct_decl","handle_token","handle_typedef","into","into","into","into","into","into","into","into","into","into","into","new","new","new","new","new","new","new","new","new","new","new","next_token","parse_action","parse_actionref","parse_actions","parse_apply","parse_assignment","parse_body","parse_body","parse_body","parse_body","parse_body","parse_call","parse_constant","parse_default_action","parse_direction","parse_entries","parse_entry","parse_expr_parameters","parse_expression","parse_key","parse_keyset","parse_match_kind","parse_package_parameters","parse_parameterized_call","parse_parameters","parse_parameters","parse_parameters","parse_sized_variable","parse_state","parse_statement_block","parse_table","parse_transition","parse_type_parameters","parse_variable","run","run","run","run","run","run","run","run","run","run","run","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","PreprocessorElements","PreprocessorResult","borrow","borrow","borrow_mut","borrow_mut","default","default","elements","fmt","fmt","from","from","includes","into","into","lines","run","try_from","try_from","try_into","try_into","type_id","type_id","resolve_lvalue"],"q":[[0,"p4"],[8,"p4::ast"],[1017,"p4::check"],[1135,"p4::error"],[1211,"p4::hlir"],[1235,"p4::lexer"],[1361,"p4::parser"],[1515,"p4::preprocessor"],[1539,"p4::util"],[1540,"core::cmp"],[1541,"core::fmt"],[1542,"core::fmt"],[1543,"core::hash"],[1544,"alloc::string"],[1545,"std::collections::hash::map"],[1546,"alloc::boxed"],[1547,"alloc::vec"],[1548,"core::result"],[1549,"core::any"],[1550,"alloc::sync"]],"d":["","","","","","","","","","","","","","","","","","","","","","","","","","A function or method call","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return all the tables in this control block, recursively …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","The first token of this parser, used for error reporting.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Level of this diagnostic.","Check lvalue references","Message associated with this diagnostic.","","","","Ensure the parser has a start state","","","The first token from the lexical element where the …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Token where the error was encountered","Token where the error was encountered","","","","","","","","","","","Column where the token error was encountered.","The soruce file where the token error was encountered.","The soruce file where the token error was encountered.","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","Returns the argument unchanged.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Length of the erronious token.","Line where the token error was encountered.","Token where the error was encountered","Message associated with this error.","Message associated with this error.","Message associated with this error.","The source line the token error occured on.","The source line the token error occured on.","The source line the token error occured on.","The source line the token error occured on.","","","","","","","","","","","","","","","","","","","","","The P4 high level intermediate representation (hlir) is a …","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","A bit literal. The following a literal examples and their …","","","","","","","","","","","","","","End of file.","","","","","","","","","","","","","","An integer literal. The following are literal examples and …","","","","","","","","","","","","","","","","","","","","","","","","","A signed literal. The following a literal examples and …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Column number of the first character in this token.","","","The file this token came from.","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","The kind of token this is.","","Line number of this token.","","","","","","","","","","","","","","","","","","Parser for parsing control definitions","","Top level parser for parsing elements are global scope.","","This is a recurisve descent parser for the P4 language.","Parser for parsing parser definitions","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Calls U::from(self).","Calls U::from(self).","","","","","","","","",""],"i":[0,0,0,0,0,0,0,0,0,0,7,45,0,45,0,12,28,0,41,7,12,41,12,7,41,0,41,28,0,0,28,0,45,0,45,0,25,0,25,0,28,12,7,27,0,25,0,0,54,7,0,12,12,0,54,0,45,7,28,0,42,42,41,7,41,0,0,12,7,41,45,27,12,0,41,12,25,0,45,12,0,0,0,12,42,0,0,0,45,0,27,25,33,28,0,33,0,41,41,0,7,45,0,0,7,0,54,0,45,12,0,7,27,0,28,0,0,42,7,0,7,0,28,0,0,7,12,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,3,38,39,40,23,3,38,39,40,3,38,39,40,17,22,17,31,3,38,39,40,29,30,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,3,38,39,40,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,44,22,3,38,39,40,3,38,39,40,1,17,3,38,39,40,3,38,39,40,1,46,18,1,43,34,22,44,19,19,21,34,29,3,38,39,40,29,12,7,11,12,17,42,44,45,3,38,39,40,3,38,39,40,1,1,4,5,6,7,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,17,1,1,1,36,17,1,18,1,17,1,11,44,3,38,39,40,3,38,39,40,1,3,38,39,40,9,10,4,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,17,18,22,3,38,39,40,3,38,39,40,23,35,11,44,31,3,38,39,40,3,38,39,40,13,15,36,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,1,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,4,5,6,8,9,10,13,14,15,16,17,18,19,20,21,22,26,44,32,35,36,37,19,21,13,15,17,18,20,36,4,5,6,11,13,15,17,18,20,22,26,32,3,38,39,40,3,38,39,40,3,38,39,40,3,38,39,40,1,3,38,39,40,1,4,5,10,17,18,20,26,34,37,3,38,39,40,1,44,44,44,44,29,30,37,44,3,38,39,40,3,38,39,40,22,3,38,39,40,3,38,39,40,20,43,32,18,3,38,39,40,1,3,38,39,40,17,17,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,7,10,11,14,16,18,22,24,26,44,32,36,3,38,39,40,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,8,9,10,14,16,19,21,46,19,21,3,38,39,40,54,1,4,5,6,7,8,9,10,11,41,12,13,14,15,16,17,18,19,42,43,20,21,22,23,24,25,26,27,28,29,30,31,44,32,33,34,35,36,37,45,46,6,5,6,17,18,37,3,38,39,40,1,24,3,38,39,40,17,0,0,69,0,0,69,0,0,69,0,0,0,69,0,92,66,93,94,95,67,68,69,65,92,66,93,94,95,67,68,69,65,66,92,93,94,95,92,92,66,66,67,67,67,92,67,67,92,92,92,92,68,69,68,69,65,93,69,65,65,68,69,65,92,66,93,94,95,67,68,69,65,92,66,93,94,95,67,68,69,65,68,93,68,65,65,67,93,68,69,68,92,66,93,94,95,67,68,69,65,92,66,93,94,95,67,68,69,65,92,66,93,94,95,67,68,69,65,0,73,73,0,0,73,0,0,70,71,70,71,72,73,74,70,71,72,73,74,72,72,74,70,70,71,71,72,72,73,73,74,74,70,71,72,73,73,73,73,74,70,71,72,73,74,72,72,74,70,71,74,70,71,72,74,70,71,72,73,74,70,71,72,73,74,70,71,72,73,74,70,71,72,73,74,0,0,75,64,75,64,64,75,64,64,75,64,75,75,64,64,75,75,75,64,75,64,75,64,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,0,77,0,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,77,0,77,77,77,77,77,76,77,58,76,77,58,76,77,58,77,58,76,58,77,58,58,77,77,58,58,76,77,58,77,58,76,77,58,58,76,58,76,76,76,77,58,77,58,76,77,58,76,77,58,76,77,58,0,0,0,0,0,0,0,0,0,0,0,80,79,81,82,83,84,85,86,87,88,89,80,79,81,82,83,84,85,86,87,88,89,80,79,81,82,83,84,85,86,87,88,89,79,79,79,79,79,79,79,79,79,79,80,79,81,82,83,84,85,86,87,88,89,80,79,81,82,83,84,85,86,87,88,89,80,81,83,83,81,84,81,83,87,88,89,84,80,83,80,83,83,80,80,83,80,83,79,84,80,82,87,82,87,80,81,80,80,80,80,79,81,82,83,84,85,86,87,88,89,80,79,81,82,83,84,85,86,87,88,89,80,79,81,82,83,84,85,86,87,88,89,80,79,81,82,83,84,85,86,87,88,89,0,0,90,91,90,91,90,91,90,90,91,90,91,91,90,91,90,0,90,91,90,91,90,91,0],"f":"```````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````{{bc}df}{{hc}df}{{jc}df}{{lc}df}{{nc}df}{{A`c}df}{{Abc}df}{{Adc}df}{{Afc}df}{{Ahc}df}{{Ajc}df}{{Alc}df}{{Anc}df}{{B`c}df}{{Bbc}df}{{Bdc}df}{{Bfc}df}{{Bhc}df}{{Bjc}df}{{Blc}df}{{Bnc}df}{{C`c}df}{{Cbc}df}{{Cdc}df}{{Cfc}df}{{Chc}df}{{Cjc}df}{{Clc}df}{{Cnc}df}{{D`c}df}{{Dbc}df}{{Ddc}df}{{Dfc}df}{{Dhc}df}{{Djc}df}{{bc}dDl}{{hc}dDl}{{jc}dDl}{{lc}dDl}{{nc}dDl}{{A`c}dDl}{{Abc}dDl}{{Adc}dDl}{{Afc}dDl}{{Ahc}dDl}{{Ajc}dDl}{{Alc}dDl}{{Anc}dDl}{{B`c}dDl}{{Bbc}dDl}{{Bdc}dDl}{{Bfc}dDl}{{Bhc}dDl}{{Bjc}dDl}{{Blc}dDl}{{Bnc}dDl}{{C`c}dDl}{{Cbc}dDl}{{Cdc}dDl}{{Cfc}dDl}{{Chc}dDl}{{Cjc}dDl}{{Clc}dDl}{{Cnc}dDl}{{D`c}dDl}{{Dbc}dDl}{{Ddc}dDl}{{Dfc}dDl}{{Dhc}dDl}{{Djc}dDl}{{fBh}d}{{DlBh}d}{{DnBh}d}{{E`Bh}d}`{{fBj}d}{{DlBj}d}{{DnBj}d}{{E`Bj}d}{{fCd}d}{{DlCd}d}{{DnCd}d}{{E`Cd}d}````{{fAh}d}{{DlAh}d}{{DnAh}d}{{E`Ah}d}``{ce{}{}}00000000000000000000000000000000000000000000000000000000000000000000000000000000000{{fCn}d}{{DlCn}d}{{DnCn}d}{{E`Cn}d}{nn}{A`A`}{AbAb}{AdAd}{AfAf}{EbEb}{AhAh}{AjAj}{AlAl}{AnAn}{B`B`}{BbBb}{BdBd}{BfBf}{EdEd}{EfEf}{BhBh}{BjBj}{BlBl}{BnBn}{C`C`}{CbCb}{CdCd}{CfCf}{ChCh}{CjCj}{ClCl}{CnCn}{EhEh}{D`D`}{DbDb}{DdDd}{DfDf}{DhDh}{DjDj}{EjEj}{ElEl}{{ce}d{}{}}000000000000000000000000000000000000{{EhEh}En}`{{fBn}d}{{DlBn}d}{{DnBn}d}{{E`Bn}d}{{fAb}d}{{DlAb}d}{{DnAb}d}{{E`Ab}d}``{{fBb}d}{{DlBb}d}{{DnBb}d}{{E`Bb}d}{{fBf}d}{{DlBf}d}{{DnBf}d}{{E`Bf}d}```{{}b}{{}Ef}{{}Dd}`{EhF`}`````{{fCl}d}{{DlCl}d}{{DnCl}d}{{E`Cl}d}`{AhFb}{{nn}Fd}{{AfAf}Fd}{{AhAh}Fd}{{BbBb}Fd}{{EdEd}Fd}{{EhEh}Fd}{{EjEj}Fd}{{fAf}d}{{DlAf}d}{{DnAf}d}{{E`Af}d}{{fDj}d}{{DlDj}d}{{DnDj}d}{{E`Dj}d}`{{bFf}Fh}{{hFf}Fh}{{jFf}Fh}{{lFf}Fh}{{nFf}Fh}0{{A`Ff}Fh}{{AbFf}Fh}{{AdFf}Fh}{{AfFf}Fh}{{EbFf}Fh}{{AhFf}Fh}{{AjFf}Fh}{{AlFf}Fh}{{AnFf}Fh}{{B`Ff}Fh}{{BbFf}Fh}{{BdFf}Fh}{{BfFf}Fh}{{EdFf}Fh}{{EfFf}Fh}{{BhFf}Fh}{{BjFf}Fh}{{BlFf}Fh}{{BnFf}Fh}{{C`Ff}Fh}{{CbFf}Fh}{{CdFf}Fh}{{CfFf}Fh}{{ChFf}Fh}{{CjFf}Fh}{{ClFf}Fh}{{CnFf}Fh}{{EhFf}Fh}{{D`Ff}Fh}{{DbFf}Fh}{{DdFf}Fh}{{DfFf}Fh}{{DhFf}Fh}{{DjFf}Fh}{{EjFf}Fh}{{ElFf}Fh}{cc{}}00000000000000000000000000000000000000000{{BbFb}{{Fj{Bh}}}}{{bFb}{{Fj{Bb}}}}{{bFb}{{Fj{Dh}}}}{{bFb}{{Fj{Aj}}}}{{DhFb}{{Fj{Dj}}}}{{BbFb}{{Fj{Bf}}}}{{bFb}{{Fj{Bd}}}}{Bd{{Fj{D`}}}}{{bFb}{{Fj{An}}}}{{BbFb}{{Fj{Bl}}}}{{bFb}{{Fj{Fl}}}}{{Afc}dFn}{{Ehc}dFn}{{fAj}d}{{DlAj}d}{{DnAj}d}{{E`Aj}d}{{fAl}d}{{DlAl}d}{{DnAl}d}{{E`Al}d}`{{fCj}d}{{DlCj}d}{{DnCj}d}{{E`Cj}d}```{ce{}{}}00000000000000000000000000000000000000000{{BbFb}Fd}{{BdFb}Fd}`{{fC`}d}{{DlC`}d}{{DnC`}d}{{E`C`}d}{{fCb}d}{{DlCb}d}{{DnCb}d}{{E`Cb}d}```{EhFb}`{{fEh}d}{{DlEh}d}{{DnEh}d}{{E`Eh}d}{{fCf}d}{{DlCf}d}{{DnCf}d}{{E`Cf}d}```{{bc}dDn}{{hc}dDn}{{jc}dDn}{{lc}dDn}{{nc}dDn}{{A`c}dDn}{{Abc}dDn}{{Adc}dDn}{{Afc}dDn}{{Ahc}dDn}{{Ajc}dDn}{{Alc}dDn}{{Anc}dDn}{{B`c}dDn}{{Bbc}dDn}{{Bdc}dDn}{{Bfc}dDn}{{Bhc}dDn}{{Bjc}dDn}{{Blc}dDn}{{Bnc}dDn}{{C`c}dDn}{{Cbc}dDn}{{Cdc}dDn}{{Cfc}dDn}{{Chc}dDn}{{Cjc}dDn}{{Clc}dDn}{{Cnc}dDn}{{D`c}dDn}{{Dbc}dDn}{{Ddc}dDn}{{Dfc}dDn}{{Dhc}dDn}{{Djc}dDn}{{bc}dE`}{{hc}dE`}{{jc}dE`}{{lc}dE`}{{nc}dE`}{{A`c}dE`}{{Abc}dE`}{{Adc}dE`}{{Afc}dE`}{{Ahc}dE`}{{Ajc}dE`}{{Alc}dE`}{{Anc}dE`}{{B`c}dE`}{{Bbc}dE`}{{Bdc}dE`}{{Bfc}dE`}{{Bhc}dE`}{{Bjc}dE`}{{Blc}dE`}{{Bnc}dE`}{{C`c}dE`}{{Cbc}dE`}{{Cdc}dE`}{{Cfc}dE`}{{Chc}dE`}{{Cjc}dE`}{{Clc}dE`}{{Cnc}dE`}{{D`c}dE`}{{Dbc}dE`}{{Ddc}dE`}{{Dfc}dE`}{{Dhc}dE`}{{Djc}dE`}````````````````````````{Aj{{Gb{G`El}}}}{An{{Gb{G`El}}}}{Bb{{Gb{G`El}}}}{Bd{{Gb{G`El}}}}{Bh{{Gb{G`El}}}}{Dh{{Gb{G`El}}}}{G`h}{G`j}{G`l}{{GdEb}{{Gf{Af}}}}{G`Aj}{G`An}{G`Bb}{{G`Gd}Bd}{G`Bh}{{G`Gd}Bl}{{G`Gd}Cd}{{G`Gd}D`}{{fDh}d}{{DlDh}d}{{DnDh}d}{{E`Dh}d}{{fAn}d}{{DlAn}d}{{DnAn}d}{{E`An}d}{{fj}d}{{Dlj}d}{{Dnj}d}{{E`j}d}{{fh}d}{{Dlh}d}{{Dnh}d}{{E`h}d}`{{fl}d}{{Dll}d}{{Dnl}d}{{E`l}d}``````````{{fBd}d}{{DlBd}d}{{DnBd}d}{{E`Bd}d}`{{EhEh}{{Fj{En}}}}{Eh{{Gh{Fb}}}}{EhEh}0```{EhFb}{{fDd}d}{{DlDd}d}{{DnDd}d}{{E`Dd}d}{{fDf}d}{{DlDf}d}{{DnDf}d}{{E`Df}d}`{{fD`}d}{{DlD`}d}{{DnD`}d}{{E`D`}d}{{fCh}d}{{DlCh}d}{{DnCh}d}{{E`Ch}d}````{{fB`}d}{{DlB`}d}{{DnB`}d}{{E`B`}d}`{{fBl}d}{{DlBl}d}{{DnBl}d}{{E`Bl}d}{{Bbb}{{Gh{{Gj{{Gh{{Gj{G`Bb}}}}Bl}}}}}}`{ce{}{}}000000000000000000000000000000000000{cG`{}}```````````{{fDb}d}{{DlDb}d}{{DnDb}d}{{E`Db}d}{c{{Gl{e}}}{}{}}00000000000000000000000000000000000000000000000000000000000000000000000000000000000``````````{{fn}d}{{Dln}d}{{Dnn}d}{{E`n}d}{cGn{}}00000000000000000000000000000000000000000``````{{fA`}d}{{DlA`}d}{{DnA`}d}{{E`A`}d}``{{fAd}d}{{DlAd}d}{{DnAd}d}{{E`Ad}d}``````````````{b{{Gj{H`Hb}}}}{ce{}{}}00000000000000000{{HdCn}d}{{BbbH`}Hb}{{Bdb}Hb}{{Anb}Hb}{{Ajb}Hb}{{BbbH`Hb}d}0{{HdCnBb}d}{{HdCnBl}d}{{HfF`}Hb}0{{HfAf{Gb{G`El}}}Hb}{{BbbHb}d}2{{HfEf{Gb{G`El}}}Hb}{{BbBl{Gb{G`El}}bHb}d}{{BbBlbHb}d}{{Bb{Gb{G`El}}bHb}d}4{HhHh}{HjHj}{{ce}d{}{}}0{{}Hb}{{D`Hb}d}{{HjHj}Fd}{Hb{{Gh{Hh}}}}{{HbHb}d}{{HhFf}Fh}{{HjFf}Fh}{{HbFf}Fh}{cc{}}00000000{ce{}{}}00000000`{{BdbHb}d}`:{{HbHh}d}{Hf{{Gj{{Gb{Afn}}Hb}}}}{{BdHb}d}44`{c{{Gl{e}}}{}{}}00000000000000000{cGn{}}00000000``````````6666666666```{{HlFf}Fh}0{{HnFf}Fh}0{{I`Ff}Fh}0{{IbFf}Fh}0{{IdFf}Fh}0<<<<{{{Gh{Hl}}}Ib}{I`Ib}{HnIb}?>>>>>``````````{cG`{}}0000::::::::::99999``????{{}H`}``{{H`Ff}Fh}{cc{}}0`{ce{}{}}0`{bIf}{Ifd}{c{{Gl{e}}}{}{}}000{cGn{}}0```````````````````````````````````````````````````````````````````````````````444444{IhFd}{IjIj}{GdGd}{{ce}d{}{}}0``{{IjIj}Fd}{{GdGd}Fd}`{{IjFf}Fh}0{{GdFf}Fh}0==={{Ijc}dFn}{{Gdc}dFn}>>>```{{{Gh{Fb}}{Il{G`}}}Ih}{Ih{{Gl{GdI`}}}}`{ce{}{}}0{cG`{}}0??????>>>```````````1111111111111111111111{cc{}}0000000000{{Inb}{{Gl{dIb}}}}0000{{InG`b}{{Gl{dIb}}}}{{InbGd}{{Gl{dIb}}}}2{{InGdb}{{Gl{dIb}}}}366666666666{IhJ`}{J`In}{J`Jb}{J`Jd}{J`Jf}{J`Jh}{J`Jj}{J`Jl}{{J`Gd}Jn}{J`K`}{J`Kb}{J`{{Gl{GdIb}}}}{{JbBb}{{Gl{dIb}}}}{Jf{{Gl{CdIb}}}}{{JfBl}{{Gl{dIb}}}}2{{JhEh}{{Gl{ChIb}}}}31{{JnBd}{{Gl{dIb}}}}{{K`D`}{{Gl{dIb}}}}{{KbDd}{{Gl{dIb}}}}3{J`{{Gl{AbIb}}}}5{J`{{Gl{{Gj{EdGd}}Ib}}}}6{Jf{{Gl{BnIb}}}}{J`{{Gl{{Gh{{Gf{Af}}}}Ib}}}}{J`{{Gl{{Gf{Af}}Ib}}}}9{J`{{Gl{{Gh{C`}}Ib}}}}{Jf{{Gl{CfIb}}}}{{Inj}{{Gl{dIb}}}};{J`{{Gl{{Gh{Bf}}Ib}}}}{{JdBh}{{Gl{dIb}}}}<{{Jdn}{{Gl{AdIb}}}}={J`{{Gl{EfIb}}}}{{JbBb}{{Gl{dIb}}}}{J`{{Gl{DbIb}}}}{J`{{Gl{{Gh{G`}}Ib}}}}{J`{{Gl{AdIb}}}}{{J`b}{{Gl{dIb}}}}{{Inb}{{Gl{dIb}}}}{Jb{{Gl{BbIb}}}}{Jd{{Gl{BhIb}}}}{Jf{{Gl{BlIb}}}}{Jh{{Gl{ChIb}}}}{Jj{{Gl{ChIb}}}}{Jl{{Gl{{Gf{Af}}Ib}}}}{Jn{{Gl{BdIb}}}}{K`{{Gl{D`Ib}}}}{Kb{{Gl{DdIb}}}}{c{{Gl{e}}}{}{}}000000000000000000000{cGn{}}0000000000``{ce{}{}}000{{}Kd}{{}Kf}`{{KdFf}Fh}{{KfFf}Fh}{cc{}}0`55`{{Fb{Il{G`}}}{{Gl{KdId}}}}888877{{Ehb{Gb{G`El}}}{{Gl{ElG`}}}}","c":[],"p":[[5,"AST",8],[1,"unit"],[10,"Visitor",8],[5,"PackageInstance",8],[5,"Package",8],[5,"PackageParameter",8],[6,"Type",8],[5,"Typedef",8],[5,"Constant",8],[5,"Variable",8],[5,"Expression",8],[6,"BinOp",8],[5,"Header",8],[5,"HeaderMember",8],[5,"Struct",8],[5,"StructMember",8],[5,"Control",8],[5,"Parser",8],[5,"ControlParameter",8],[5,"Action",8],[5,"ActionParameter",8],[5,"Table",8],[5,"ConstTableEntry",8],[5,"KeySetElement",8],[6,"KeySetElementValue",8],[5,"ActionRef",8],[6,"MatchKind",8],[6,"Statement",8],[5,"IfBlock",8],[5,"ElseIfBlock",8],[5,"Call",8],[5,"State",8],[6,"Transition",8],[5,"Select",8],[5,"SelectElement",8],[5,"Extern",8],[5,"ExternMethod",8],[10,"VisitorMut",8],[10,"MutVisitor",8],[10,"MutVisitorMut",8],[6,"ExpressionKind",8],[6,"Direction",8],[5,"StatementBlock",8],[5,"Lvalue",8],[6,"DeclarationInfo",8],[5,"NameInfo",8],[6,"Ordering",1540],[1,"usize"],[1,"str"],[1,"bool"],[5,"Formatter",1541],[8,"Result",1541],[6,"Option",1542],[6,"UserDefinedType",8],[10,"Hasher",1543],[5,"String",1544],[5,"HashMap",1545],[5,"Token",1235],[5,"Box",1546],[5,"Vec",1547],[1,"tuple"],[6,"Result",1548],[5,"TypeId",1549],[5,"Hlir",1211],[5,"Diagnostics",1017],[5,"ApplyCallChecker",1017],[5,"ExpressionTypeChecker",1017],[5,"Diagnostic",1017],[6,"Level",1017],[5,"SemanticError",1135],[5,"ParserError",1135],[5,"TokenError",1135],[6,"Error",1135],[5,"PreprocessorError",1135],[5,"HlirGenerator",1211],[5,"Lexer",1235],[6,"Kind",1235],[5,"Arc",1550],[5,"GlobalParser",1361],[5,"Parser",1361],[5,"ControlParser",1361],[5,"ActionParser",1361],[5,"TableParser",1361],[5,"StatementParser",1361],[5,"IfElseParser",1361],[5,"ExpressionParser",1361],[5,"ParserParser",1361],[5,"StateParser",1361],[5,"SelectParser",1361],[5,"PreprocessorResult",1515],[5,"PreprocessorElements",1515],[5,"ControlChecker",1017],[5,"ParserChecker",1017],[5,"StructChecker",1017],[5,"HeaderChecker",1017]],"b":[[441,"impl-Debug-for-Type"],[442,"impl-Display-for-Type"],[1158,"impl-Debug-for-SemanticError"],[1159,"impl-Display-for-SemanticError"],[1160,"impl-Debug-for-ParserError"],[1161,"impl-Display-for-ParserError"],[1162,"impl-Debug-for-TokenError"],[1163,"impl-Display-for-TokenError"],[1164,"impl-Debug-for-Error"],[1165,"impl-Display-for-Error"],[1166,"impl-Debug-for-PreprocessorError"],[1167,"impl-Display-for-PreprocessorError"],[1172,"impl-From%3CVec%3CSemanticError%3E%3E-for-Error"],[1173,"impl-From%3CTokenError%3E-for-Error"],[1174,"impl-From%3CParserError%3E-for-Error"],[1330,"impl-Debug-for-Kind"],[1331,"impl-Display-for-Kind"],[1332,"impl-Debug-for-Token"],[1333,"impl-Display-for-Token"]]}],\ +["p4_macro",{"doc":"The use_p4! macro allows for P4 programs to be directly …","t":"Q","n":["use_p4"],"q":[[0,"p4_macro"]],"d":["The use_p4! macro uses the x4c compiler to generate Rust …"],"i":[0],"f":"`","c":[],"p":[],"b":[]}],\ +["p4_macro_test",{"doc":"","t":"NNNNNNNNNNNONNOOFNNNNFNNNNHNHNNNNNNCONNNNNNNNNNONQQQQQQQQQQQQQ","n":["borrow","borrow","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","csum","default","default","dst_addr","dump","dump","ether_type","ethernet","ethernet_t","fmt","fmt","from","from","headers_t","into","into","isValid","is_valid","main","new","parsadillo_start","set","setInvalid","setValid","set_invalid","set_valid","size","softnpu_provider","src_addr","to_bitvec","to_bitvec","to_owned","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","valid","valid_header_size","action","control_apply","control_table_hit","control_table_miss","egress_accepted","egress_dropped","egress_table_hit","egress_table_miss","ingress_accepted","ingress_dropped","parser_accepted","parser_dropped","parser_transition"],"q":[[0,"p4_macro_test"],[49,"p4_macro_test::softnpu_provider"],[62,"bitvec::order"],[63,"bitvec::vec"],[64,"alloc::string"],[65,"core::fmt"],[66,"core::fmt"],[67,"p4rs::error"],[68,"core::result"],[69,"core::any"]],"d":["","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[1,2,1,2,1,2,1,2,1,1,2,1,1,2,1,2,0,1,2,1,2,0,1,2,1,1,0,1,0,1,1,1,1,1,1,0,1,1,2,1,2,1,2,1,2,1,2,1,2,0,0,0,0,0,0,0,0,0,0,0,0,0],"f":"{ce{}{}}000{bb}{dd}{{ce}f{}{}}0{b{{l{hj}}}}{{}b}{{}d}`{bn}{dn}```{{bA`}Ab}{{dA`}Ab}{cc{}}0`;;{bAd}0{{}f}8{{Afd}Ad}{{b{Ah{h}}}{{Al{fAj}}}}{bf}000{{}An}``={d{{l{hj}}}}{ce{}{}}0{c{{Al{e}}}{}{}}000{cB`{}}0`{dAn}`````````````","c":[],"p":[[5,"ethernet_t",0],[5,"headers_t",0],[1,"unit"],[1,"u8"],[5,"Msb0",62],[5,"BitVec",63],[5,"String",64],[5,"Formatter",65],[8,"Result",65],[1,"bool"],[5,"packet_in",66],[1,"slice"],[5,"TryFromSliceError",67],[6,"Result",68],[1,"usize"],[5,"TypeId",69]],"b":[]}],\ +["p4_rust",{"doc":"","t":"FFNNNNNNHHNNNNNNOHNNNNNNNN","n":["Sanitizer","Settings","action_parameter","borrow","borrow","borrow_mut","borrow_mut","control_parameter","emit","emit_tokens","from","from","header_member","into","into","lvalue","pipeline_name","sanitize","sanitize_string","struct_member","try_from","try_from","try_into","try_into","type_id","type_id"],"q":[[0,"p4_rust"],[26,"p4::ast"],[27,"p4::ast"],[28,"std::io::error"],[29,"proc_macro2"],[30,"p4::ast"],[31,"p4::ast"],[32,"core::any"]],"d":["","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","Calls U::from(self).","Calls U::from(self).","","Name to give to the C-ABI constructor.","","","","","","","","",""],"i":[0,0,1,8,1,8,1,1,0,0,8,1,1,8,1,1,8,0,1,1,8,1,8,1,8,1],"f":"``{{bd}f}{ce{}{}}000{{bh}f}{{jlnA`}{{Ab{f}}}}{{jlA`}Ad}{cc{}}0{{bAf}f}55{{bAh}f}`{jf}{Ajf}{{bAl}f}{c{{An{e}}}{}{}}000{cB`{}}0","c":[],"p":[[5,"Sanitizer",0],[5,"ActionParameter",26],[1,"unit"],[5,"ControlParameter",26],[5,"AST",26],[5,"Hlir",27],[1,"str"],[5,"Settings",0],[8,"Result",28],[5,"TokenStream",29],[5,"HeaderMember",26],[5,"Lvalue",26],[5,"String",30],[5,"StructMember",26],[6,"Result",31],[5,"TypeId",32]],"b":[]}],\ +["p4rs",{"doc":"This is the runtime support create for x4c generated …","t":"FFKKFEOMCHHHNNNNNNNNNNCONHNCCNHHHHNHHNNNNNNNNNNMMNOOHNNNNNMOMNNFFOOMMNMMMMCMNNNNNNNNNNNNNNNHHHHHKFNNNNNNMNNNNNNNHFNNNNNNNNNNFNNNNNNNNNNFPPGPPFPFFGPPOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNNNNNNNNNNNNOHHONONOOHNNNNHHNNNNNNNNNNNNNNNNNNNNNNNNOO","n":["AlignedU128","Bit","Header","Pipeline","TableEntry","TryFromSliceError","action_id","add_table_entry","bitmath","bitvec_to_biguint","bitvec_to_bitvec16","bitvec_to_ip6addr","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","checksum","data","deserialize","dump_bv","eq","error","externs","extract","extract_bit_action_parameter","extract_bool_action_parameter","extract_exact_key","extract_lpm_key","extract_new","extract_range_key","extract_ternary_key","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","get_table_entries","get_table_ids","hash","header_data","index","int_to_bitvec","into","into","into","into","into","is_valid","keyset_data","new","new","new","packet_in","packet_out","parameter_data","payload_data","process_packet","remove_table_entry","serialize","set","set_invalid","set_valid","size","table","to_bitvec","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","add_be","add_generic","add_le","mod_be","mod_le","Checksum","Csum","add","add128","add16","add32","borrow","borrow_mut","csum","default","from","into","result","try_from","try_into","type_id","udp6_checksum","TryFromSliceError","borrow","borrow_mut","fmt","fmt","from","into","to_string","try_from","try_into","type_id","Checksum","borrow","borrow_mut","default","from","into","new","run","try_from","try_into","type_id","BigUintKey","DontCare","Exact","Key","Lpm","Masked","Prefix","Range","Table","TableEntry","Ternary","Ternary","Value","action","action_id","addr","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","default","default","default","deserialize","deserialize","deserialize","deserialize","dump","entries","eq","eq","eq","eq","eq","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","hash","hash","hash","hash","hash","into","into","into","into","into","into","key","key_matches","keyset_matches","len","match_selector","name","new","parameter_data","priority","prune_entries_by_lpm","serialize","serialize","serialize","serialize","sort_entries","sort_entries_by_priority","to_bytes","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","value","width"],"q":[[0,"p4rs"],[91,"p4rs::bitmath"],[96,"p4rs::checksum"],[113,"p4rs::error"],[124,"p4rs::externs"],[135,"p4rs::table"],[251,"bitvec::order"],[252,"bitvec::vec"],[253,"core::net::ip_addr"],[254,"core::result"],[255,"serde::de"],[256,"alloc::string"],[257,"core::fmt"],[258,"core::fmt"],[259,"core::option"],[260,"core::hash"],[261,"serde::ser"],[262,"core::any"],[263,"core::clone"],[264,"num_bigint::biguint"]],"d":["","","A fixed length header trait.","","","","","Add an entry to a table identified by table_id.","","","","","","","","","","","","","","","","The underlying data. Owned by an external, memory-mapped …","","","","","","","","","","","","","Extract a ternary key from the provided keyset data. …","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Get all the entries in a table.","Get a list of table ids","","","Extraction index. Everything before index has been …","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","Every packet that goes through a P4 pipeline is …","","","","Process an input packet and produce a set of output …","Remove an entry from a table identified by table_id.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","","","","Returns the argument unchanged.","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,0,0,0,0,0,11,1,0,0,0,0,43,15,17,24,11,43,15,17,24,11,0,17,11,0,15,0,0,17,0,0,0,0,17,0,0,15,15,17,24,11,43,15,17,24,11,1,1,15,24,17,0,43,15,17,24,11,18,11,18,15,17,0,0,11,24,1,1,11,18,18,18,18,0,18,43,15,17,24,11,43,15,17,24,11,43,15,17,24,11,0,0,0,0,0,0,0,33,33,33,33,33,33,35,33,33,33,33,33,33,33,0,0,21,21,21,21,21,21,21,21,21,21,0,36,36,36,36,36,36,36,36,36,36,0,37,20,0,20,37,0,20,0,0,0,20,37,39,39,38,41,9,20,37,38,39,41,9,20,37,38,39,9,20,37,38,39,9,20,37,38,39,41,20,37,9,20,37,38,41,41,9,20,37,38,39,9,20,37,38,39,41,9,20,37,38,39,9,20,37,38,39,41,9,20,37,38,39,39,0,0,38,41,39,41,39,39,0,9,20,37,38,0,0,20,9,20,37,38,39,41,9,20,37,38,39,41,9,20,37,38,39,41,9,20,37,38,39,9,9],"f":"```````{{bdd{h{f}}{h{f}}j}l}`{{{A`{fn}}}Ab}{{{A`{fn}}}{{A`{fn}}}}{{{A`{fn}}}Ad}{ce{}{}}000000000``{c{{Ah{Af}}}Aj}{{{A`{fn}}}Al}{{AnAn}B`}``{{Bbc}lBd}{{{h{f}}BfBf}{{A`{fn}}}}{{{h{f}}Bf}B`}{{{h{f}}BfBf}Bh}0{Bb{{Ah{cBj}}}Bd}11{{AnBl}Bn}0{{BbBl}Bn}{{C`Bl}Bn}{{AfBl}Bn}{cc{}}0000{{bd}{{Cd{{Cb{Af}}}}}}{b{{Cb{d}}}}{{Anc}lCf}``{Ch{{A`{fn}}}}{ce{}{}}0000{BdB`}`{{}Bd}{{{h{f}}}{{Ah{AnBj}}}}{{{h{f}}}Bb}````{{bCjBb}{{Cb{{Cl{C`Cj}}}}}}{{bd{h{f}}}l}{{Afc}AhCn}{{Bd{h{f}}}{{Ah{lBj}}}}{Bdl}0{{}Bf}`{Bd{{A`{fn}}}}{c{{Ah{e}}}{}{}}000000000{cD`{}}0000{{{A`{fn}}{A`{fn}}}{{A`{fn}}}}0000``{{Dbff}l}{{Db{Dd{f}}}l}00{ce{}{}}0{Df{{A`{fn}}}}{{}Db}{cc{}}3{DbCj}998{{{h{f}}}Cj}`55{{BjBl}Bn}036{cAl{}}<<;`77{{}Dh}580{{Dh{h{Df}}}{{A`{fn}}}}>>=````````````````999999999999{AbAb}{BhBh}{DjDj}{DlDl}{{{Dn{c}}}{{Dn{c}}}{E`E`}}{{ce}l{}{}}0000{{}{{Eb{c}}}E`}{{}Bh}{{}Dj}{c{{Ah{Ab}}}Aj}{c{{Ah{Bh}}}Aj}{c{{Ah{Dj}}}Aj}{c{{Ah{Dl}}}Aj}{{{Eb{c}}}AlE`}`{{AbAb}B`}{{BhBh}B`}{{DjDj}B`}{{DlDl}B`}{{{Dn{c}}{Dn{c}}}B`E`}{{AbBl}Bn}{{BhBl}Bn}{{DjBl}Bn}{{DlBl}Bn}{{{Dn{c}}Bl}BnE`}{cc{}}00000{{Abc}lCf}{{Bhc}lCf}{{Djc}lCf}{{Dlc}lCf}{{{Dn{c}}e}lE`Cf}{ce{}{}}00000`{{EdBh}B`}{{{Dd{Ed}}{Dd{Bh}}}B`}`{{{Eb{c}}{Dd{Ed}}}{{Cb{{Dn{c}}}}}E`}`{{}{{Eb{c}}}E`}``{{Bf{Cb{{Dn{c}}}}}{{Cb{{Dn{c}}}}}E`}{{Abc}AhCn}{{Bhc}AhCn}{{Djc}AhCn}{{Dlc}AhCn}{{{Cb{{Dn{c}}}}}{{Cb{{Dn{c}}}}}E`}{{{h{{Dn{c}}}}}lE`}{Bh{{Cb{f}}}}<<<<<{c{{Ah{e}}}{}{}}00000000000{cD`{}}00000``","c":[],"p":[[10,"Pipeline",0],[1,"str"],[1,"u8"],[1,"slice"],[1,"u32"],[1,"unit"],[5,"Msb0",251],[5,"BitVec",252],[5,"BigUintKey",135],[6,"IpAddr",253],[5,"TableEntry",0],[6,"Result",254],[10,"Deserializer",255],[5,"String",256],[5,"Bit",0],[1,"bool"],[5,"packet_in",0],[10,"Header",0],[1,"usize"],[6,"Key",135],[5,"TryFromSliceError",113],[5,"Formatter",257],[8,"Result",257],[5,"packet_out",0],[5,"Vec",258],[6,"Option",259],[10,"Hasher",260],[1,"i128"],[1,"u16"],[1,"tuple"],[10,"Serializer",261],[5,"TypeId",262],[5,"Csum",96],[1,"array"],[10,"Checksum",96],[5,"Checksum",124],[6,"Ternary",135],[5,"Prefix",135],[5,"TableEntry",135],[10,"Clone",263],[5,"Table",135],[5,"BigUint",264],[5,"AlignedU128",0]],"b":[[37,"impl-Debug-for-Bit%3C\'a,+N%3E"],[38,"impl-LowerHex-for-Bit%3C\'a,+N%3E"],[116,"impl-Debug-for-TryFromSliceError"],[117,"impl-Display-for-TryFromSliceError"]]}],\ +["sidecar_lite",{"doc":"","t":"HOONNNNNNNNNNNNNOFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNOOOOOOOOOOOOOOOOOOOOFFNNNNNNNNNNNNNNNOOOOOOOOOOHFOOFOOONNNNNNNNNNNNNNNONNNNNNNNNNNNNNNNOFNNNNNNNNNNNNNNOOOFOOOOFOOOOHHOHOHOFHOHOHOHOHOHOHOHOHOOOOOONNNNNNNNNNNNNNNNOFOFNNNNNNNNNNNNOHHHHHFOOHHNNNNNNNNNNNNNOOOOOOOHHHHHHHHHHHHHHHOOOONOOOOHHNNNNNNNNNNNNNOOOOHHHHHHHOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOFNNNNNNNNNNNNOOOOOOOOFONNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNOFOOOOOOOOOOOOOOOOOOFOO","n":["_main_pipeline_create","ack","ack_no","add_ingress_local_local_v4_entry","add_ingress_local_local_v6_entry","add_ingress_mac_mac_rewrite_entry","add_ingress_nat_nat_icmp_v4_entry","add_ingress_nat_nat_icmp_v6_entry","add_ingress_nat_nat_v4_entry","add_ingress_nat_nat_v6_entry","add_ingress_pxarp_proxy_arp_entry","add_ingress_resolver_resolver_v4_entry","add_ingress_resolver_resolver_v6_entry","add_ingress_router_router_v4_entry","add_ingress_router_router_v6_entry","add_table_entry","arp","arp_h","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","checksum","checksum","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","code","crit","csum","csum","csum","csum","csum","csum","csum","csum","csum","csum","csum","csum","ctrl","data","data_offset","ddm","ddm0","ddm1","ddm10","ddm11","ddm12","ddm13","ddm14","ddm15","ddm2","ddm3","ddm4","ddm5","ddm6","ddm7","ddm8","ddm9","ddm_element_t","ddm_h","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","dei","diffserv","drop","drop","dst","dst","dst","dst_port","dst_port","egress","egress_apply","egress_metadata_t","ether_type","ethernet","ethernet_h","flags","flags","flow_label","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","frag_offset","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","geneve","geneve_h","get_ingress_local_local_v4_entries","get_ingress_local_local_v6_entries","get_ingress_mac_mac_rewrite_entries","get_ingress_nat_nat_icmp_v4_entries","get_ingress_nat_nat_icmp_v6_entries","get_ingress_nat_nat_v4_entries","get_ingress_nat_nat_v6_entries","get_ingress_pxarp_proxy_arp_entries","get_ingress_resolver_resolver_v4_entries","get_ingress_resolver_resolver_v6_entries","get_ingress_router_router_v4_entries","get_ingress_router_router_v6_entries","get_table_entries","get_table_ids","hdr_checksum","hdr_checksum","header_length","headers_t","hop_limit","hw_addr_len","hw_type","icmp","icmp_h","id","identification","ihl","ingress","ingress_apply","ingress_local_local_v4","ingress_local_local_v4","ingress_local_local_v6","ingress_local_local_v6","ingress_mac_mac_rewrite","ingress_mac_mac_rewrite","ingress_metadata_t","ingress_nat_nat_icmp_v4","ingress_nat_nat_icmp_v4","ingress_nat_nat_icmp_v6","ingress_nat_nat_icmp_v6","ingress_nat_nat_v4","ingress_nat_nat_v4","ingress_nat_nat_v6","ingress_nat_nat_v6","ingress_pxarp_proxy_arp","ingress_pxarp_proxy_arp","ingress_resolver_resolver_v4","ingress_resolver_resolver_v4","ingress_resolver_resolver_v6","ingress_resolver_resolver_v6","ingress_router_router_v4","ingress_router_router_v4","ingress_router_router_v6","ingress_router_router_v6","inner_eth","inner_ipv4","inner_ipv6","inner_tcp","inner_udp","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","ipv4","ipv4_h","ipv6","ipv6_h","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","len","local_action_local","local_action_nonlocal","local_apply","mac_rewrite_action_rewrite","mac_rewrite_apply","main_pipeline","nat","nat_id","nat_ingress_action_forward_to_sled","nat_ingress_apply","new","new","new","new","new","new","new","new","new","new","new","new","new","next_hdr","next_header","nexthop_v4","nexthop_v6","opcode","opt_len","parse","parse_arp","parse_ddm","parse_geneve","parse_icmp","parse_inner_eth","parse_inner_ipv4","parse_inner_ipv6","parse_inner_tcp","parse_inner_udp","parse_ipv4","parse_ipv6","parse_sidecar","parse_start","parse_tcp","parse_udp","payload_len","pcp","port","port","process_packet","proto_addr_len","proto_type","protocol","protocol","proxy_arp_action_proxy_arp_reply","proxy_arp_apply","remove_ingress_local_local_v4_entry","remove_ingress_local_local_v6_entry","remove_ingress_mac_mac_rewrite_entry","remove_ingress_nat_nat_icmp_v4_entry","remove_ingress_nat_nat_icmp_v6_entry","remove_ingress_nat_nat_v4_entry","remove_ingress_nat_nat_v6_entry","remove_ingress_pxarp_proxy_arp_entry","remove_ingress_resolver_resolver_v4_entry","remove_ingress_resolver_resolver_v6_entry","remove_ingress_router_router_v4_entry","remove_ingress_router_router_v6_entry","remove_table_entry","res","reserved","reserved","reserved2","resolver_action_drop","resolver_action_rewrite_dst","resolver_apply","router_action_drop","router_action_forward_v4","router_action_forward_v6","router_apply","sc_code","sc_egress","sc_ether_type","sc_ingress","sc_payload","sender_ip","sender_mac","seq_no","set","set","set","set","set","set","set","set","set","set","set","set","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","sidecar","sidecar_h","size","size","size","size","size","size","size","size","size","size","size","size","src","src","src","src_port","src_port","target_ip","target_mac","tcp","tcp_h","timestamp","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","total_len","traffic_class","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","ttl","typ","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","udp","udp_h","urgent_ptr","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid","version","version","version","version","vid","vlan_h","vni","window"],"q":[[0,"sidecar_lite"],[527,"p4rs"],[528,"bitvec::order"],[529,"bitvec::vec"],[530,"core::fmt"],[531,"core::fmt"],[532,"core::option"],[533,"core::ops::function"],[534,"alloc::sync"],[535,"p4rs::table"],[536,"p4rs::externs"],[537,"p4rs"],[538,"core::result"],[539,"core::any"]],"d":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,10,9,3,3,3,3,3,3,3,3,3,3,3,3,3,20,0,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,21,9,23,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,17,22,9,10,11,12,13,15,16,17,18,19,22,23,22,17,9,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,20,0,0,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,12,16,14,21,15,16,18,9,23,3,0,0,18,20,0,9,16,15,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,16,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,20,0,3,3,3,3,3,3,3,3,3,3,3,3,3,3,16,17,10,0,15,19,19,20,0,13,16,16,3,0,0,3,0,3,0,3,0,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,0,3,20,20,20,20,20,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,20,0,20,0,9,10,11,12,13,15,16,17,18,19,22,23,23,0,0,0,0,0,0,14,14,0,0,3,9,10,11,12,13,15,16,17,18,19,22,23,15,10,21,21,19,22,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,15,12,14,21,3,19,19,16,22,0,0,3,3,3,3,3,3,3,3,3,3,3,3,3,9,10,22,22,0,0,0,0,0,0,0,11,11,11,11,11,19,19,9,9,10,11,12,13,15,16,17,18,19,22,23,9,10,11,12,13,15,16,17,18,19,22,23,9,10,11,12,13,15,16,17,18,19,22,23,20,0,9,10,11,12,13,15,16,17,18,19,22,23,15,16,18,9,23,19,19,20,0,13,9,10,11,12,13,15,16,17,18,19,22,23,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,16,15,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,16,17,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,20,0,9,9,10,11,12,13,15,16,17,18,19,22,23,10,15,16,22,12,0,22,9],"f":"{bd}``{{fh{l{j}}{l{j}}n}A`}00000000000{{fhh{l{j}}{l{j}}n}A`}``{ce{}{}}0000000000000000000000000000000```{AbAb}{AdAd}{AfAf}{AhAh}{AjAj}{AlAl}{AnAn}{B`B`}{BbBb}{BdBd}{BfBf}{BhBh}{BjBj}{BlBl}{BnBn}{{ce}A`{}{}}00000000000000``{Ab{{Cb{jC`}}}}{Ad{{Cb{jC`}}}}{Af{{Cb{jC`}}}}{Ah{{Cb{jC`}}}}{Aj{{Cb{jC`}}}}{An{{Cb{jC`}}}}{B`{{Cb{jC`}}}}{Bb{{Cb{jC`}}}}{Bd{{Cb{jC`}}}}{Bf{{Cb{jC`}}}}{Bl{{Cb{jC`}}}}{Bn{{Cb{jC`}}}}``````````````````````{{}Ab}{{}Ad}{{}Af}{{}Ah}{{}Aj}{{}Al}{{}An}{{}B`}{{}Bb}{{}Bd}{{}Bf}{{}Bh}{{}Bj}{{}Bl}{{}Bn}``````````{{BhAlBj}A`}```````{{AbCd}Cf}{{AdCd}Cf}{{AfCd}Cf}{{AhCd}Cf}{{AjCd}Cf}{{AlCd}Cf}{{AnCd}Cf}{{B`Cd}Cf}{{BbCd}Cf}{{BdCd}Cf}{{BfCd}Cf}{{BhCd}Cf}{{BjCd}Cf}{{BlCd}Cf}{{BnCd}Cf}`{cc{}}000000000000000``{f{{Cj{Ch}}}}00000000000{{fh}{{Cl{{Cj{Ch}}}}}}{f{{Cj{h}}}}`````````````{{BhAlBj{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}}A`}{{}{{Db{{D`{Cn}}}}}}`0`0``0`0`0`0`0`0`0`0`0``````{ce{}{}}000000000000000````{AbDd}{AdDd}{AfDd}{AhDd}{AjDd}{AnDd}{B`Dd}{BbDd}{BdDd}{BfDd}{BlDd}{BnDd}`{{BhDd}A`}0{{BhDd{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}}A`}{{BhBj{Cb{jC`}}}A`}{{BhBj{Db{{D`{Cn}}}}}A`}```{{BhAlBjDf{Cb{jC`}}{Cb{jC`}}{Cb{jC`}}}A`}{{BhAlBj{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}}A`}{bf}{{}Ab}{{}Ad}{{}Af}{{}Ah}{{}Aj}{{}An}{{}B`}{{}Bb}{{}Bd}{{}Bf}{{}Bl}{{}Bn}```````{{DhBhAl}Dd}00000000000000````{{fbDh}{{Cj{{Dl{Djb}}}}}}````{{BhAlBj{Cb{jC`}}}A`}{{BhAlBj{Db{{D`{Cn}}}}}A`}{{f{l{j}}}A`}00000000000{{fh{l{j}}}A`}````{{BhBj}A`}{{BhBj{Cb{jC`}}}A`}{{BhBj{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}}A`}{{BhAlBj}A`}{{BhAlBj{Cb{jC`}}{Cb{jC`}}}A`}0{{BhAlBj{Db{{D`{Cn}}}}{Db{{D`{Cn}}}}}A`}````````{{Ab{l{j}}}{{E`{A`Dn}}}}{{Ad{l{j}}}{{E`{A`Dn}}}}{{Af{l{j}}}{{E`{A`Dn}}}}{{Ah{l{j}}}{{E`{A`Dn}}}}{{Aj{l{j}}}{{E`{A`Dn}}}}{{An{l{j}}}{{E`{A`Dn}}}}{{B`{l{j}}}{{E`{A`Dn}}}}{{Bb{l{j}}}{{E`{A`Dn}}}}{{Bd{l{j}}}{{E`{A`Dn}}}}{{Bf{l{j}}}{{E`{A`Dn}}}}{{Bl{l{j}}}{{E`{A`Dn}}}}{{Bn{l{j}}}{{E`{A`Dn}}}}{AbA`}{AdA`}{AfA`}{AhA`}{AjA`}{AnA`}{B`A`}{BbA`}{BdA`}{BfA`}{BlA`}{BnA`};:9876543210``{{}Eb}00000000000``````````{Ab{{Cb{jC`}}}}{Ad{{Cb{jC`}}}}{Af{{Cb{jC`}}}}{Ah{{Cb{jC`}}}}{Aj{{Cb{jC`}}}}{An{{Cb{jC`}}}}{B`{{Cb{jC`}}}}{Bb{{Cb{jC`}}}}{Bd{{Cb{jC`}}}}{Bf{{Cb{jC`}}}}{Bl{{Cb{jC`}}}}{Bn{{Cb{jC`}}}}{ce{}{}}00000000000000``{c{{E`{e}}}{}{}}0000000000000000000000000000000``{cEd{}}000000000000000```````````````````````","c":[],"p":[[1,"u16"],[10,"Pipeline",527],[5,"main_pipeline",0],[1,"str"],[1,"u8"],[1,"slice"],[1,"u32"],[1,"unit"],[5,"tcp_h",0],[5,"ddm_h",0],[5,"sidecar_h",0],[5,"vlan_h",0],[5,"ddm_element_t",0],[5,"ingress_metadata_t",0],[5,"ipv6_h",0],[5,"ipv4_h",0],[5,"icmp_h",0],[5,"ethernet_h",0],[5,"arp_h",0],[5,"headers_t",0],[5,"egress_metadata_t",0],[5,"geneve_h",0],[5,"udp_h",0],[5,"Msb0",528],[5,"BitVec",529],[5,"Formatter",530],[8,"Result",530],[5,"TableEntry",527],[5,"Vec",531],[6,"Option",532],[10,"Fn",533],[5,"Arc",534],[5,"Table",535],[1,"bool"],[5,"Checksum",536],[5,"packet_in",527],[5,"packet_out",527],[1,"tuple"],[5,"TryFromSliceError",537],[6,"Result",538],[1,"usize"],[5,"TypeId",539]],"b":[]}],\ +["tests",{"doc":"","t":"CQQCCHHFFFFFFFFOONNNNNNNNNNNNNNNNNNHOOOOONNNNNNNNOONNNNNNNNONNNNNNNNNNOOONOOONNNNOOONNNOONNNNNNNNNNNNNNNNNNNNNNNNNNOOONNNNNNNN","n":["data","expect_frames","muffins","packet","softnpu","v4","v6","InnerPhy","Interface4","Interface6","OuterPhy","OwnedFrame","RxFrame","SoftNpu","TxFrame","addr","addr","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone_into","do_expect_frames","dst","dst","ethertype","ethertype","ethertype","from","from","from","from","from","from","from","from","index","index","into","into","into","into","into","into","into","into","mac","new","new","new","new","new","new","new","new","newv","newv","payload","payload","payload","phy","phy","phy","pipeline","recv","recv_buffer_len","run","rx_count","sc_egress","sc_egress","sc_egress","send","send","send","src","src","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","tx_count","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vid","vid","vid","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip"],"q":[[0,"tests"],[5,"tests::packet"],[7,"tests::softnpu"],[126,"core::net::ip_addr"],[127,"pnet_packet::ipv4"],[128,"core::net::ip_addr"],[129,"alloc::sync"],[130,"core::option"],[131,"p4rs"],[132,"xfr"],[133,"xfr"],[134,"xfr"],[135,"anyhow"],[136,"core::any"]],"d":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","Create a new SoftNpu ASIC emulator. The radix indicates …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,22,23,17,21,10,22,23,25,12,7,17,21,10,22,23,25,12,7,7,7,0,25,7,25,12,7,17,21,10,22,23,25,12,7,21,10,17,21,10,22,23,25,12,7,10,17,21,10,22,23,25,12,7,25,12,25,12,7,17,22,23,17,10,10,17,10,22,23,25,10,22,23,12,7,7,17,21,10,22,23,25,12,7,17,21,10,22,23,25,12,7,10,17,21,10,22,23,25,12,7,25,12,7,17,21,10,22,23,25,12,7],"f":"`````{{bb{f{d}}{f{d}}}h}{{jj{f{d}}{f{d}}}l}``````````{ce{}{}}000000000000000{nn}{{ce}A`{}{}}{{Ab{Af{Ad}}{f{Ah}}{Al{{Aj{d}}}}}A`}`````{cc{}}0000000``44444444`{{AncB`}{{Bb{c}}}Bd}{{AnBfBh}Bj}{{AnBhBf}Ad}{{{Af{Ad}}j}Bl}{{{Af{Ad}}b}Bn}{{{Aj{d}}C`{f{d}}}Cb}{{{Aj{d}}C`{f{d}}}Ah}{{{Aj{d}}{Aj{d}}C`{Al{C`}}{Cd{d}}}n}{{{Aj{d}}C`{f{d}}C`}Cb}{{{Aj{d}}C`{f{d}}C`}Ah}```{{{Bb{c}}An}{{Af{Ad}}}Bd}```{Ad{{Cd{n}}}}{AdAn}{{{Bb{c}}}A`Bd}1```{{Ad{f{Cb}}}{{Ch{A`Cf}}}}{{Bl{Aj{d}}j{f{d}}}{{Ch{A`Cj}}}}{{Bn{Aj{d}}b{f{d}}}{{Ch{A`Cj}}}}``{ce{}{}}{c{{Ch{e}}}{}{}}0000000000000006{cCl{}}0000000```22222222","c":[],"p":[[5,"Ipv4Addr",126],[1,"u8"],[1,"slice"],[5,"MutableIpv4Packet",127],[5,"Ipv6Addr",126],[5,"MutableIpv6Packet",128],[5,"OwnedFrame",7],[1,"unit"],[1,"str"],[5,"OuterPhy",7],[5,"Arc",129],[5,"RxFrame",7],[1,"array"],[6,"Option",130],[1,"usize"],[1,"bool"],[5,"SoftNpu",7],[10,"Pipeline",131],[5,"RingConsumer",132],[5,"RingProducer",132],[5,"InnerPhy",7],[5,"Interface6",7],[5,"Interface4",7],[1,"u16"],[5,"TxFrame",7],[5,"Vec",133],[6,"Error",132],[6,"Result",134],[5,"Error",135],[5,"TypeId",136]],"b":[]}],\ +["vlan_switch",{"doc":"","t":"HOONNNFNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNOOOFFNNNNNNNNNNNNNNNOOOOOOOOONNNNNNNNNNNNNNNOHFOOOFOOONNNNNNNNNNNNNNNHHHONNNNNNNNNNNNNNNNFNNNNOOOFOOOFOOOOHHOFHOHNNNNNNNNNNNNNNNNFFNNNNNNNNNNNNNNNNNNNNNNNNOHFOONNNNNNNNNNNNNOOOOOOOHHOOOONNOOOOONNNOOOOHOOOOOOOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNFNNNNNNNNNNNNCOOOOOOOFONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNOONNNNNNNNNNNNNNNNFOOOOOOOOOOOOONNNOOOOOOHHHFONNNNNNNNNNNNNNNNOQQQQQQQQQQQQQ","n":["_vlan_switch_pipeline_create","ack","ack_no","add_ingress_fwd_fib_entry","add_ingress_vlan_port_vlan_entry","add_table_entry","arp_h","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","broadcast","checksum","checksum","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","code","crit","csum","csum","csum","csum","csum","csum","csum","csum","csum","csum","csum","csum","ctrl","data","data_offset","ddm_element_t","ddm_h","default","default","default","default","default","default","default","default","default","default","default","default","default","default","default","dei","diffserv","drop","drop","dst","dst","dst","dst_port","dst_port","dump","dump","dump","dump","dump","dump","dump","dump","dump","dump","dump","dump","dump","dump","dump","egress","egress_apply","egress_metadata_t","eth","ether_type","ether_type","ethernet_h","flags","flags","flow_label","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","forward_action_drop","forward_action_forward","forward_apply","frag_offset","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","from","geneve_h","get_ingress_fwd_fib_entries","get_ingress_vlan_port_vlan_entries","get_table_entries","get_table_ids","hdr_checksum","hdr_checksum","header_length","headers_t","hop_limit","hw_addr_len","hw_type","icmp_h","id","identification","ihl","ingress","ingress_apply","ingress_fwd_fib","ingress_fwd_fib","ingress_metadata_t","ingress_vlan_port_vlan","ingress_vlan_port_vlan","init_tables","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","into","ipv4_h","ipv6_h","isValid","isValid","isValid","isValid","isValid","isValid","isValid","isValid","isValid","isValid","isValid","isValid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","is_valid","len","main","main_pipeline","nat","nat_id","new","new","new","new","new","new","new","new","new","new","new","new","new","next_hdr","next_header","nexthop_v4","nexthop_v6","opcode","opt_len","parse","parse_start","parse_vlan","payload_len","pcp","port","port","process_packet","process_packet_headers","proto_addr_len","proto_type","protocol","protocol","radix","remove_ingress_fwd_fib_entry","remove_ingress_vlan_port_vlan_entry","remove_table_entry","res","reserved","reserved","reserved2","run_test","sc_code","sc_egress","sc_ether_type","sc_ingress","sc_payload","sender_ip","sender_mac","seq_no","set","set","set","set","set","set","set","set","set","set","set","set","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setInvalid","setValid","setValid","setValid","setValid","setValid","setValid","setValid","setValid","setValid","setValid","setValid","setValid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_invalid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","set_valid","sidecar_h","size","size","size","size","size","size","size","size","size","size","size","size","softnpu_provider","src","src","src","src_port","src_port","target_ip","target_mac","tcp_h","timestamp","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_bitvec","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","total_len","traffic_class","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","ttl","typ","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","udp_h","urgent_ptr","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid","valid_header_size","valid_header_size","valid_header_size","version","version","version","version","vid","vlan","vlan_action_filter","vlan_action_no_vid_for_port","vlan_apply","vlan_h","vni","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","window","action","control_apply","control_table_hit","control_table_miss","egress_accepted","egress_dropped","egress_table_hit","egress_table_miss","ingress_accepted","ingress_dropped","parser_accepted","parser_dropped","parser_transition"],"q":[[0,"vlan_switch"],[505,"vlan_switch::softnpu_provider"],[518,"p4rs"],[519,"bitvec::order"],[520,"bitvec::vec"],[521,"alloc::string"],[522,"core::fmt"],[523,"core::fmt"],[524,"alloc::sync"],[525,"p4rs::table"],[526,"p4rs"],[527,"core::option"],[528,"anyhow"],[529,"core::result"],[530,"p4rs"],[531,"core::any"]],"d":["","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","","","","","","","","","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","",""],"i":[0,9,14,3,3,3,0,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,10,11,14,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,18,19,9,11,12,14,15,16,17,18,19,20,22,23,19,18,14,0,0,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,15,16,10,13,16,17,22,11,14,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,3,0,0,21,15,22,0,14,16,17,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,0,0,16,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,3,3,3,3,16,18,9,0,17,20,20,0,12,16,16,3,0,0,3,0,0,3,0,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,0,9,11,12,14,15,16,17,18,19,20,22,23,9,11,12,14,15,16,17,18,19,20,22,23,11,0,0,13,13,3,9,11,12,14,15,16,17,18,19,20,22,23,17,9,10,10,20,19,3,0,0,17,15,10,13,3,3,20,20,16,19,3,3,3,3,14,9,19,19,0,23,23,23,23,23,20,20,14,9,11,12,14,15,16,17,18,19,20,22,23,9,11,12,14,15,16,17,18,19,20,22,23,9,11,12,14,15,16,17,18,19,20,22,23,9,11,12,14,15,16,17,18,19,20,22,23,9,11,12,14,15,16,17,18,19,20,22,23,0,9,11,12,14,15,16,17,18,19,20,22,23,0,16,17,22,11,14,20,20,0,12,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,16,17,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,16,18,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,0,14,9,11,12,14,15,16,17,18,19,20,22,23,10,13,21,9,16,17,19,15,21,0,0,0,0,19,3,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,14,0,0,0,0,0,0,0,0,0,0,0,0,0],"f":"{bd}``{{fh{l{j}}{l{j}}n}A`}0{{fhh{l{j}}{l{j}}n}A`}`{ce{}{}}0000000000000000000000000000000```{AbAb}{AdAd}{AfAf}{AhAh}{AjAj}{AlAl}{AnAn}{B`B`}{BbBb}{BdBd}{BfBf}{BhBh}{BjBj}{BlBl}{BnBn}{{ce}A`{}{}}00000000000000``{Ab{{Cb{jC`}}}}{Af{{Cb{jC`}}}}{Ah{{Cb{jC`}}}}{Al{{Cb{jC`}}}}{An{{Cb{jC`}}}}{B`{{Cb{jC`}}}}{Bb{{Cb{jC`}}}}{Bd{{Cb{jC`}}}}{Bf{{Cb{jC`}}}}{Bh{{Cb{jC`}}}}{Bl{{Cb{jC`}}}}{Bn{{Cb{jC`}}}}`````{{}Ab}{{}Ad}{{}Af}{{}Ah}{{}Aj}{{}Al}{{}An}{{}B`}{{}Bb}{{}Bd}{{}Bf}{{}Bh}{{}Bj}{{}Bl}{{}Bn}`````````{AbCd}{AdCd}{AfCd}{AhCd}{AjCd}{AlCd}{AnCd}{B`Cd}{BbCd}{BdCd}{BfCd}{BhCd}{BjCd}{BlCd}{BnCd}`{{BjAjAd}A`}````````{{AbCf}Ch}{{AdCf}Ch}{{AfCf}Ch}{{AhCf}Ch}{{AjCf}Ch}{{AlCf}Ch}{{AnCf}Ch}{{B`Cf}Ch}{{BbCf}Ch}{{BdCf}Ch}{{BfCf}Ch}{{BhCf}Ch}{{BjCf}Ch}{{BlCf}Ch}{{BnCf}Ch}{{BjAd}A`}{{BjAd{Cb{jC`}}}A`}{{BjAd{Cn{{Cl{Cj}}}}}A`}`{cc{}}000000000000000`{f{{Db{D`}}}}0{{fh}{{Dd{{Db{D`}}}}}}{f{{Db{h}}}}````````````{{BjAjAd{Cn{{Cl{Cj}}}}{Cn{{Cl{Cj}}}}}A`}{{}{{Cn{{Cl{Cj}}}}}}``0`{{f{Df{j}}{Df{j}}}A`}{ce{}{}}000000000000000``{AbDh}{AfDh}{AhDh}{AlDh}{AnDh}{B`Dh}{BbDh}{BdDh}{BfDh}{BhDh}{BlDh}{BnDh};:9876543210`{{}{{Dl{A`Dj}}}}```{bf}{{}Ab}{{}Af}{{}Ah}{{}Al}{{}An}{{}B`}{{}Bb}{{}Bd}{{}Bf}{{}Bh}{{}Bl}{{}Bn}```````{{DnBjAj}Dh}0````{{fbDn}{{Db{{Eb{E`b}}}}}}{{fbDn}{{Db{{Eb{Bjb}}}}}}`````{{f{l{j}}}A`}0{{fh{l{j}}}A`}````{{f{Df{j}}{Df{j}}}{{Dl{A`Dj}}}}````````{{Ab{l{j}}}{{Dl{A`Ed}}}}{{Af{l{j}}}{{Dl{A`Ed}}}}{{Ah{l{j}}}{{Dl{A`Ed}}}}{{Al{l{j}}}{{Dl{A`Ed}}}}{{An{l{j}}}{{Dl{A`Ed}}}}{{B`{l{j}}}{{Dl{A`Ed}}}}{{Bb{l{j}}}{{Dl{A`Ed}}}}{{Bd{l{j}}}{{Dl{A`Ed}}}}{{Bf{l{j}}}{{Dl{A`Ed}}}}{{Bh{l{j}}}{{Dl{A`Ed}}}}{{Bl{l{j}}}{{Dl{A`Ed}}}}{{Bn{l{j}}}{{Dl{A`Ed}}}}{AbA`}{AfA`}{AhA`}{AlA`}{AnA`}{B`A`}{BbA`}{BdA`}{BfA`}{BhA`}{BlA`}{BnA`};:9876543210;:9876543210;:9876543210`{{}Ef}00000000000``````````{Ab{{Cb{jC`}}}}{Ad{{Cb{jC`}}}}{Af{{Cb{jC`}}}}{Ah{{Cb{jC`}}}}{Aj{{Cb{jC`}}}}{Al{{Cb{jC`}}}}{An{{Cb{jC`}}}}{B`{{Cb{jC`}}}}{Bb{{Cb{jC`}}}}{Bd{{Cb{jC`}}}}{Bf{{Cb{jC`}}}}{Bh{{Cb{jC`}}}}{Bj{{Cb{jC`}}}}{Bl{{Cb{jC`}}}}{Bn{{Cb{jC`}}}}{ce{}{}}00000000000000``{c{{Dl{e}}}{}{}}0000000000000000000000000000000``{cEh{}}000000000000000``````````````{AdEf}{AjEf}{BjEf}``````{{{Cb{jC`}}{Cb{jC`}}Dh{Cb{jC`}}}A`}{{{Cb{jC`}}{Cb{jC`}}Dh}A`}{{{Cb{jC`}}{Cb{jC`}}Dh{Cn{{Cl{Cj}}}}}A`}``8888888888888888``````````````","c":[],"p":[[1,"u16"],[10,"Pipeline",518],[5,"main_pipeline",0],[1,"str"],[1,"u8"],[1,"slice"],[1,"u32"],[1,"unit"],[5,"ddm_h",0],[5,"egress_metadata_t",0],[5,"udp_h",0],[5,"ddm_element_t",0],[5,"ingress_metadata_t",0],[5,"tcp_h",0],[5,"vlan_h",0],[5,"ipv4_h",0],[5,"ipv6_h",0],[5,"icmp_h",0],[5,"geneve_h",0],[5,"arp_h",0],[5,"headers_t",0],[5,"ethernet_h",0],[5,"sidecar_h",0],[5,"Msb0",519],[5,"BitVec",520],[5,"String",521],[5,"Formatter",522],[8,"Result",522],[10,"Fn",523],[5,"Arc",524],[5,"Table",525],[5,"TableEntry",518],[5,"Vec",526],[6,"Option",527],[1,"array"],[1,"bool"],[5,"Error",528],[6,"Result",529],[5,"packet_in",518],[5,"packet_out",518],[1,"tuple"],[5,"TryFromSliceError",530],[1,"usize"],[5,"TypeId",531]],"b":[]}],\ +["x4c",{"doc":"","t":"PFPPGNNNNNNONNONNNNNNNNOHOOOOONNNNNNNNNNN","n":["Docs","Opts","RedHawk","Rust","Target","augment_args","augment_args_for_update","borrow","borrow","borrow_mut","borrow_mut","check","clone","clone_into","filename","from","from","from_arg_matches","from_arg_matches_mut","into","into","into_app","into_app_for_update","out","process_file","show_ast","show_hlir","show_pre","show_tokens","target","to_owned","to_possible_value","try_from","try_from","try_into","try_into","type_id","type_id","update_from_arg_matches","update_from_arg_matches_mut","value_variants"],"q":[[0,"x4c"],[41,"clap::builder::command"],[42,"clap::parser::matches::arg_matches"],[43,"clap::error"],[44,"core::result"],[45,"alloc::string"],[46,"alloc::sync"],[47,"p4::ast"],[48,"anyhow"],[49,"clap::builder::possible_value"],[50,"core::option"],[51,"core::any"]],"d":["","","","","","","","","","","","Just check code, do not compile.","","","File to compile.","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","","","Filename to write generated code to.","","Show parsed abstract syntax tree.","Show high-level intermediate representation info.","Show parsed preprocessor info.","Show parsed lexical tokens.","What target to generate code for.","","","","","","","","","","",""],"i":[2,0,2,2,0,5,5,5,2,5,2,5,2,2,5,5,2,5,5,5,2,5,5,5,0,5,5,5,5,5,2,2,5,2,5,2,5,2,5,5,2],"f":"`````{bb}0{ce{}{}}000`{dd}{{ce}f{}{}}`{cc{}}0{h{{n{jl}}}}044{{}b}0`{{{Ab{A`}}Adj}{{Af{f}}}}`````6{d{{Aj{Ah}}}}{c{{n{e}}}{}{}}000{cAl{}}0{{jh}{{n{fl}}}}0{{}{{An{d}}}}","c":[],"p":[[8,"Command",41],[6,"Target",0],[1,"unit"],[5,"ArgMatches",42],[5,"Opts",0],[5,"Error",43],[6,"Result",44],[5,"String",45],[5,"Arc",46],[5,"AST",47],[8,"Result",48],[5,"PossibleValue",49],[6,"Option",50],[5,"TypeId",51],[1,"slice"]],"b":[]}],\ +["x4c_error_codes",{"doc":"","t":"","n":[],"q":[],"d":[],"i":[],"f":"","c":[],"p":[],"b":[]}]\ +]')); +if (typeof exports !== 'undefined') exports.searchIndex = searchIndex; +else if (window.initSearch) window.initSearch(searchIndex); diff --git a/settings.html b/settings.html new file mode 100644 index 00000000..76419d06 --- /dev/null +++ b/settings.html @@ -0,0 +1,2 @@ +Settings +

Rustdoc settings

Back
\ No newline at end of file diff --git a/sidecar_lite/all.html b/sidecar_lite/all.html new file mode 100644 index 00000000..31ae17c6 --- /dev/null +++ b/sidecar_lite/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/sidecar_lite/fn._main_pipeline_create.html b/sidecar_lite/fn._main_pipeline_create.html new file mode 100644 index 00000000..a9eeca15 --- /dev/null +++ b/sidecar_lite/fn._main_pipeline_create.html @@ -0,0 +1,5 @@ +_main_pipeline_create in sidecar_lite - Rust +
#[no_mangle]
+pub extern "C" fn _main_pipeline_create(
+    radix: u16
+) -> *mut dyn Pipeline
\ No newline at end of file diff --git a/sidecar_lite/fn.egress_apply.html b/sidecar_lite/fn.egress_apply.html new file mode 100644 index 00000000..5ff52a4a --- /dev/null +++ b/sidecar_lite/fn.egress_apply.html @@ -0,0 +1,6 @@ +egress_apply in sidecar_lite - Rust +

Function sidecar_lite::egress_apply

source ·
pub fn egress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_apply.html b/sidecar_lite/fn.ingress_apply.html new file mode 100644 index 00000000..1e3a410f --- /dev/null +++ b/sidecar_lite/fn.ingress_apply.html @@ -0,0 +1,18 @@ +ingress_apply in sidecar_lite - Rust +
pub fn ingress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    local_local_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>,
+    local_local_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>,
+    router_router_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>,
+    router_router_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>,
+    nat_nat_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    nat_nat_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    nat_nat_icmp_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    nat_nat_icmp_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    resolver_resolver_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>,
+    resolver_resolver_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>,
+    mac_mac_rewrite: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>,
+    pxarp_proxy_arp: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_local_local_v4.html b/sidecar_lite/fn.ingress_local_local_v4.html new file mode 100644 index 00000000..01113d01 --- /dev/null +++ b/sidecar_lite/fn.ingress_local_local_v4.html @@ -0,0 +1,3 @@ +ingress_local_local_v4 in sidecar_lite - Rust +
pub fn ingress_local_local_v4(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_local_local_v6.html b/sidecar_lite/fn.ingress_local_local_v6.html new file mode 100644 index 00000000..7cb32b93 --- /dev/null +++ b/sidecar_lite/fn.ingress_local_local_v6.html @@ -0,0 +1,3 @@ +ingress_local_local_v6 in sidecar_lite - Rust +
pub fn ingress_local_local_v6(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_mac_mac_rewrite.html b/sidecar_lite/fn.ingress_mac_mac_rewrite.html new file mode 100644 index 00000000..64879136 --- /dev/null +++ b/sidecar_lite/fn.ingress_mac_mac_rewrite.html @@ -0,0 +1,3 @@ +ingress_mac_mac_rewrite in sidecar_lite - Rust +
pub fn ingress_mac_mac_rewrite(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_nat_nat_icmp_v4.html b/sidecar_lite/fn.ingress_nat_nat_icmp_v4.html new file mode 100644 index 00000000..eee64db9 --- /dev/null +++ b/sidecar_lite/fn.ingress_nat_nat_icmp_v4.html @@ -0,0 +1,3 @@ +ingress_nat_nat_icmp_v4 in sidecar_lite - Rust +
pub fn ingress_nat_nat_icmp_v4(
+) -> Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_nat_nat_icmp_v6.html b/sidecar_lite/fn.ingress_nat_nat_icmp_v6.html new file mode 100644 index 00000000..d030b98f --- /dev/null +++ b/sidecar_lite/fn.ingress_nat_nat_icmp_v6.html @@ -0,0 +1,3 @@ +ingress_nat_nat_icmp_v6 in sidecar_lite - Rust +
pub fn ingress_nat_nat_icmp_v6(
+) -> Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_nat_nat_v4.html b/sidecar_lite/fn.ingress_nat_nat_v4.html new file mode 100644 index 00000000..b33262ca --- /dev/null +++ b/sidecar_lite/fn.ingress_nat_nat_v4.html @@ -0,0 +1,3 @@ +ingress_nat_nat_v4 in sidecar_lite - Rust +
pub fn ingress_nat_nat_v4(
+) -> Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_nat_nat_v6.html b/sidecar_lite/fn.ingress_nat_nat_v6.html new file mode 100644 index 00000000..0337a6e6 --- /dev/null +++ b/sidecar_lite/fn.ingress_nat_nat_v6.html @@ -0,0 +1,3 @@ +ingress_nat_nat_v6 in sidecar_lite - Rust +
pub fn ingress_nat_nat_v6(
+) -> Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_pxarp_proxy_arp.html b/sidecar_lite/fn.ingress_pxarp_proxy_arp.html new file mode 100644 index 00000000..c1c3688c --- /dev/null +++ b/sidecar_lite/fn.ingress_pxarp_proxy_arp.html @@ -0,0 +1,3 @@ +ingress_pxarp_proxy_arp in sidecar_lite - Rust +
pub fn ingress_pxarp_proxy_arp(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_resolver_resolver_v4.html b/sidecar_lite/fn.ingress_resolver_resolver_v4.html new file mode 100644 index 00000000..19cac9ff --- /dev/null +++ b/sidecar_lite/fn.ingress_resolver_resolver_v4.html @@ -0,0 +1,3 @@ +ingress_resolver_resolver_v4 in sidecar_lite - Rust +
pub fn ingress_resolver_resolver_v4(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_resolver_resolver_v6.html b/sidecar_lite/fn.ingress_resolver_resolver_v6.html new file mode 100644 index 00000000..aa9e94c8 --- /dev/null +++ b/sidecar_lite/fn.ingress_resolver_resolver_v6.html @@ -0,0 +1,3 @@ +ingress_resolver_resolver_v6 in sidecar_lite - Rust +
pub fn ingress_resolver_resolver_v6(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_router_router_v4.html b/sidecar_lite/fn.ingress_router_router_v4.html new file mode 100644 index 00000000..ab07dcb1 --- /dev/null +++ b/sidecar_lite/fn.ingress_router_router_v4.html @@ -0,0 +1,3 @@ +ingress_router_router_v4 in sidecar_lite - Rust +
pub fn ingress_router_router_v4(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.ingress_router_router_v6.html b/sidecar_lite/fn.ingress_router_router_v6.html new file mode 100644 index 00000000..d7012c33 --- /dev/null +++ b/sidecar_lite/fn.ingress_router_router_v6.html @@ -0,0 +1,3 @@ +ingress_router_router_v6 in sidecar_lite - Rust +
pub fn ingress_router_router_v6(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/sidecar_lite/fn.local_action_local.html b/sidecar_lite/fn.local_action_local.html new file mode 100644 index 00000000..fc0ac466 --- /dev/null +++ b/sidecar_lite/fn.local_action_local.html @@ -0,0 +1,2 @@ +local_action_local in sidecar_lite - Rust +
pub fn local_action_local(hdr: &mut headers_t, is_local: &mut bool)
\ No newline at end of file diff --git a/sidecar_lite/fn.local_action_nonlocal.html b/sidecar_lite/fn.local_action_nonlocal.html new file mode 100644 index 00000000..f7a172b5 --- /dev/null +++ b/sidecar_lite/fn.local_action_nonlocal.html @@ -0,0 +1,2 @@ +local_action_nonlocal in sidecar_lite - Rust +
pub fn local_action_nonlocal(hdr: &mut headers_t, is_local: &mut bool)
\ No newline at end of file diff --git a/sidecar_lite/fn.local_apply.html b/sidecar_lite/fn.local_apply.html new file mode 100644 index 00000000..250955c3 --- /dev/null +++ b/sidecar_lite/fn.local_apply.html @@ -0,0 +1,7 @@ +local_apply in sidecar_lite - Rust +

Function sidecar_lite::local_apply

source ·
pub fn local_apply(
+    hdr: &mut headers_t,
+    is_local: &mut bool,
+    local_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>,
+    local_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.mac_rewrite_action_rewrite.html b/sidecar_lite/fn.mac_rewrite_action_rewrite.html new file mode 100644 index 00000000..65c4b0b5 --- /dev/null +++ b/sidecar_lite/fn.mac_rewrite_action_rewrite.html @@ -0,0 +1,6 @@ +mac_rewrite_action_rewrite in sidecar_lite - Rust +
pub fn mac_rewrite_action_rewrite(
+    hdr: &mut headers_t,
+    egress: &mut egress_metadata_t,
+    mac: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.mac_rewrite_apply.html b/sidecar_lite/fn.mac_rewrite_apply.html new file mode 100644 index 00000000..63bc9e7e --- /dev/null +++ b/sidecar_lite/fn.mac_rewrite_apply.html @@ -0,0 +1,6 @@ +mac_rewrite_apply in sidecar_lite - Rust +
pub fn mac_rewrite_apply(
+    hdr: &mut headers_t,
+    egress: &mut egress_metadata_t,
+    mac_rewrite: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.nat_ingress_action_forward_to_sled.html b/sidecar_lite/fn.nat_ingress_action_forward_to_sled.html new file mode 100644 index 00000000..f6570ac5 --- /dev/null +++ b/sidecar_lite/fn.nat_ingress_action_forward_to_sled.html @@ -0,0 +1,10 @@ +nat_ingress_action_forward_to_sled in sidecar_lite - Rust +
pub fn nat_ingress_action_forward_to_sled(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    csum: &Checksum,
+    target: BitVec<u8, Msb0>,
+    vni: BitVec<u8, Msb0>,
+    mac: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.nat_ingress_apply.html b/sidecar_lite/fn.nat_ingress_apply.html new file mode 100644 index 00000000..11f7fb0e --- /dev/null +++ b/sidecar_lite/fn.nat_ingress_apply.html @@ -0,0 +1,10 @@ +nat_ingress_apply in sidecar_lite - Rust +
pub fn nat_ingress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    nat_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    nat_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    nat_icmp_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>,
+    nat_icmp_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_arp.html b/sidecar_lite/fn.parse_arp.html new file mode 100644 index 00000000..d8e356ed --- /dev/null +++ b/sidecar_lite/fn.parse_arp.html @@ -0,0 +1,6 @@ +parse_arp in sidecar_lite - Rust +

Function sidecar_lite::parse_arp

source ·
pub fn parse_arp(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_ddm.html b/sidecar_lite/fn.parse_ddm.html new file mode 100644 index 00000000..20b4f63d --- /dev/null +++ b/sidecar_lite/fn.parse_ddm.html @@ -0,0 +1,6 @@ +parse_ddm in sidecar_lite - Rust +

Function sidecar_lite::parse_ddm

source ·
pub fn parse_ddm(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_geneve.html b/sidecar_lite/fn.parse_geneve.html new file mode 100644 index 00000000..68d0217c --- /dev/null +++ b/sidecar_lite/fn.parse_geneve.html @@ -0,0 +1,6 @@ +parse_geneve in sidecar_lite - Rust +

Function sidecar_lite::parse_geneve

source ·
pub fn parse_geneve(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_icmp.html b/sidecar_lite/fn.parse_icmp.html new file mode 100644 index 00000000..a628023d --- /dev/null +++ b/sidecar_lite/fn.parse_icmp.html @@ -0,0 +1,6 @@ +parse_icmp in sidecar_lite - Rust +

Function sidecar_lite::parse_icmp

source ·
pub fn parse_icmp(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_inner_eth.html b/sidecar_lite/fn.parse_inner_eth.html new file mode 100644 index 00000000..13d0cdbf --- /dev/null +++ b/sidecar_lite/fn.parse_inner_eth.html @@ -0,0 +1,6 @@ +parse_inner_eth in sidecar_lite - Rust +
pub fn parse_inner_eth(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_inner_ipv4.html b/sidecar_lite/fn.parse_inner_ipv4.html new file mode 100644 index 00000000..d322fa42 --- /dev/null +++ b/sidecar_lite/fn.parse_inner_ipv4.html @@ -0,0 +1,6 @@ +parse_inner_ipv4 in sidecar_lite - Rust +
pub fn parse_inner_ipv4(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_inner_ipv6.html b/sidecar_lite/fn.parse_inner_ipv6.html new file mode 100644 index 00000000..39e565e8 --- /dev/null +++ b/sidecar_lite/fn.parse_inner_ipv6.html @@ -0,0 +1,6 @@ +parse_inner_ipv6 in sidecar_lite - Rust +
pub fn parse_inner_ipv6(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_inner_tcp.html b/sidecar_lite/fn.parse_inner_tcp.html new file mode 100644 index 00000000..c8d5b692 --- /dev/null +++ b/sidecar_lite/fn.parse_inner_tcp.html @@ -0,0 +1,6 @@ +parse_inner_tcp in sidecar_lite - Rust +
pub fn parse_inner_tcp(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_inner_udp.html b/sidecar_lite/fn.parse_inner_udp.html new file mode 100644 index 00000000..b8aaaf76 --- /dev/null +++ b/sidecar_lite/fn.parse_inner_udp.html @@ -0,0 +1,6 @@ +parse_inner_udp in sidecar_lite - Rust +
pub fn parse_inner_udp(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_ipv4.html b/sidecar_lite/fn.parse_ipv4.html new file mode 100644 index 00000000..1ffa0005 --- /dev/null +++ b/sidecar_lite/fn.parse_ipv4.html @@ -0,0 +1,6 @@ +parse_ipv4 in sidecar_lite - Rust +

Function sidecar_lite::parse_ipv4

source ·
pub fn parse_ipv4(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_ipv6.html b/sidecar_lite/fn.parse_ipv6.html new file mode 100644 index 00000000..f2cdb1fa --- /dev/null +++ b/sidecar_lite/fn.parse_ipv6.html @@ -0,0 +1,6 @@ +parse_ipv6 in sidecar_lite - Rust +

Function sidecar_lite::parse_ipv6

source ·
pub fn parse_ipv6(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_sidecar.html b/sidecar_lite/fn.parse_sidecar.html new file mode 100644 index 00000000..f30046df --- /dev/null +++ b/sidecar_lite/fn.parse_sidecar.html @@ -0,0 +1,6 @@ +parse_sidecar in sidecar_lite - Rust +
pub fn parse_sidecar(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_start.html b/sidecar_lite/fn.parse_start.html new file mode 100644 index 00000000..039a0ae7 --- /dev/null +++ b/sidecar_lite/fn.parse_start.html @@ -0,0 +1,6 @@ +parse_start in sidecar_lite - Rust +

Function sidecar_lite::parse_start

source ·
pub fn parse_start(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_tcp.html b/sidecar_lite/fn.parse_tcp.html new file mode 100644 index 00000000..c8517e14 --- /dev/null +++ b/sidecar_lite/fn.parse_tcp.html @@ -0,0 +1,6 @@ +parse_tcp in sidecar_lite - Rust +

Function sidecar_lite::parse_tcp

source ·
pub fn parse_tcp(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.parse_udp.html b/sidecar_lite/fn.parse_udp.html new file mode 100644 index 00000000..8ec68fd8 --- /dev/null +++ b/sidecar_lite/fn.parse_udp.html @@ -0,0 +1,6 @@ +parse_udp in sidecar_lite - Rust +

Function sidecar_lite::parse_udp

source ·
pub fn parse_udp(
+    pkt: &mut packet_in<'_>,
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/sidecar_lite/fn.proxy_arp_action_proxy_arp_reply.html b/sidecar_lite/fn.proxy_arp_action_proxy_arp_reply.html new file mode 100644 index 00000000..0442014d --- /dev/null +++ b/sidecar_lite/fn.proxy_arp_action_proxy_arp_reply.html @@ -0,0 +1,7 @@ +proxy_arp_action_proxy_arp_reply in sidecar_lite - Rust +
pub fn proxy_arp_action_proxy_arp_reply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    mac: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.proxy_arp_apply.html b/sidecar_lite/fn.proxy_arp_apply.html new file mode 100644 index 00000000..3cabbfbe --- /dev/null +++ b/sidecar_lite/fn.proxy_arp_apply.html @@ -0,0 +1,7 @@ +proxy_arp_apply in sidecar_lite - Rust +
pub fn proxy_arp_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    proxy_arp: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.resolver_action_drop.html b/sidecar_lite/fn.resolver_action_drop.html new file mode 100644 index 00000000..f747d316 --- /dev/null +++ b/sidecar_lite/fn.resolver_action_drop.html @@ -0,0 +1,2 @@ +resolver_action_drop in sidecar_lite - Rust +
pub fn resolver_action_drop(hdr: &mut headers_t, egress: &mut egress_metadata_t)
\ No newline at end of file diff --git a/sidecar_lite/fn.resolver_action_rewrite_dst.html b/sidecar_lite/fn.resolver_action_rewrite_dst.html new file mode 100644 index 00000000..fa924741 --- /dev/null +++ b/sidecar_lite/fn.resolver_action_rewrite_dst.html @@ -0,0 +1,6 @@ +resolver_action_rewrite_dst in sidecar_lite - Rust +
pub fn resolver_action_rewrite_dst(
+    hdr: &mut headers_t,
+    egress: &mut egress_metadata_t,
+    dst: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.resolver_apply.html b/sidecar_lite/fn.resolver_apply.html new file mode 100644 index 00000000..a2023407 --- /dev/null +++ b/sidecar_lite/fn.resolver_apply.html @@ -0,0 +1,7 @@ +resolver_apply in sidecar_lite - Rust +
pub fn resolver_apply(
+    hdr: &mut headers_t,
+    egress: &mut egress_metadata_t,
+    resolver_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>,
+    resolver_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.router_action_drop.html b/sidecar_lite/fn.router_action_drop.html new file mode 100644 index 00000000..5024def2 --- /dev/null +++ b/sidecar_lite/fn.router_action_drop.html @@ -0,0 +1,6 @@ +router_action_drop in sidecar_lite - Rust +
pub fn router_action_drop(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.router_action_forward_v4.html b/sidecar_lite/fn.router_action_forward_v4.html new file mode 100644 index 00000000..b7cdf502 --- /dev/null +++ b/sidecar_lite/fn.router_action_forward_v4.html @@ -0,0 +1,8 @@ +router_action_forward_v4 in sidecar_lite - Rust +
pub fn router_action_forward_v4(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    port: BitVec<u8, Msb0>,
+    nexthop: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.router_action_forward_v6.html b/sidecar_lite/fn.router_action_forward_v6.html new file mode 100644 index 00000000..bbef1a9b --- /dev/null +++ b/sidecar_lite/fn.router_action_forward_v6.html @@ -0,0 +1,8 @@ +router_action_forward_v6 in sidecar_lite - Rust +
pub fn router_action_forward_v6(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    port: BitVec<u8, Msb0>,
+    nexthop: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/sidecar_lite/fn.router_apply.html b/sidecar_lite/fn.router_apply.html new file mode 100644 index 00000000..dac18e2f --- /dev/null +++ b/sidecar_lite/fn.router_apply.html @@ -0,0 +1,8 @@ +router_apply in sidecar_lite - Rust +

Function sidecar_lite::router_apply

source ·
pub fn router_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    router_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>,
+    router_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/sidecar_lite/index.html b/sidecar_lite/index.html new file mode 100644 index 00000000..14349c7e --- /dev/null +++ b/sidecar_lite/index.html @@ -0,0 +1,3 @@ +sidecar_lite - Rust +
\ No newline at end of file diff --git a/sidecar_lite/sidebar-items.js b/sidecar_lite/sidebar-items.js new file mode 100644 index 00000000..bcbb3c76 --- /dev/null +++ b/sidecar_lite/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["_main_pipeline_create","egress_apply","ingress_apply","ingress_local_local_v4","ingress_local_local_v6","ingress_mac_mac_rewrite","ingress_nat_nat_icmp_v4","ingress_nat_nat_icmp_v6","ingress_nat_nat_v4","ingress_nat_nat_v6","ingress_pxarp_proxy_arp","ingress_resolver_resolver_v4","ingress_resolver_resolver_v6","ingress_router_router_v4","ingress_router_router_v6","local_action_local","local_action_nonlocal","local_apply","mac_rewrite_action_rewrite","mac_rewrite_apply","nat_ingress_action_forward_to_sled","nat_ingress_apply","parse_arp","parse_ddm","parse_geneve","parse_icmp","parse_inner_eth","parse_inner_ipv4","parse_inner_ipv6","parse_inner_tcp","parse_inner_udp","parse_ipv4","parse_ipv6","parse_sidecar","parse_start","parse_tcp","parse_udp","proxy_arp_action_proxy_arp_reply","proxy_arp_apply","resolver_action_drop","resolver_action_rewrite_dst","resolver_apply","router_action_drop","router_action_forward_v4","router_action_forward_v6","router_apply"],"struct":["arp_h","ddm_element_t","ddm_h","egress_metadata_t","ethernet_h","geneve_h","headers_t","icmp_h","ingress_metadata_t","ipv4_h","ipv6_h","main_pipeline","sidecar_h","tcp_h","udp_h","vlan_h"]}; \ No newline at end of file diff --git a/sidecar_lite/struct.arp_h.html b/sidecar_lite/struct.arp_h.html new file mode 100644 index 00000000..fca6d468 --- /dev/null +++ b/sidecar_lite/struct.arp_h.html @@ -0,0 +1,103 @@ +arp_h in sidecar_lite - Rust +

Struct sidecar_lite::arp_h

source ·
pub struct arp_h {
+    pub valid: bool,
+    pub hw_type: BitVec<u8, Msb0>,
+    pub proto_type: BitVec<u8, Msb0>,
+    pub hw_addr_len: BitVec<u8, Msb0>,
+    pub proto_addr_len: BitVec<u8, Msb0>,
+    pub opcode: BitVec<u8, Msb0>,
+    pub sender_mac: BitVec<u8, Msb0>,
+    pub sender_ip: BitVec<u8, Msb0>,
+    pub target_mac: BitVec<u8, Msb0>,
+    pub target_ip: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§hw_type: BitVec<u8, Msb0>§proto_type: BitVec<u8, Msb0>§hw_addr_len: BitVec<u8, Msb0>§proto_addr_len: BitVec<u8, Msb0>§opcode: BitVec<u8, Msb0>§sender_mac: BitVec<u8, Msb0>§sender_ip: BitVec<u8, Msb0>§target_mac: BitVec<u8, Msb0>§target_ip: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for arp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for arp_h

source§

fn clone(&self) -> arp_h

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 Debug for arp_h

source§

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

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

impl Default for arp_h

source§

fn default() -> arp_h

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

impl Header for arp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for arp_h

§

impl Send for arp_h

§

impl Sync for arp_h

§

impl Unpin for arp_h

§

impl UnwindSafe for arp_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.ddm_element_t.html b/sidecar_lite/struct.ddm_element_t.html new file mode 100644 index 00000000..0e00578b --- /dev/null +++ b/sidecar_lite/struct.ddm_element_t.html @@ -0,0 +1,96 @@ +ddm_element_t in sidecar_lite - Rust +
pub struct ddm_element_t {
+    pub valid: bool,
+    pub id: BitVec<u8, Msb0>,
+    pub timestamp: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§id: BitVec<u8, Msb0>§timestamp: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for ddm_element_t

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ddm_element_t

source§

fn clone(&self) -> ddm_element_t

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 Debug for ddm_element_t

source§

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

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

impl Default for ddm_element_t

source§

fn default() -> ddm_element_t

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

impl Header for ddm_element_t

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.ddm_h.html b/sidecar_lite/struct.ddm_h.html new file mode 100644 index 00000000..21ac3f89 --- /dev/null +++ b/sidecar_lite/struct.ddm_h.html @@ -0,0 +1,99 @@ +ddm_h in sidecar_lite - Rust +

Struct sidecar_lite::ddm_h

source ·
pub struct ddm_h {
+    pub valid: bool,
+    pub next_header: BitVec<u8, Msb0>,
+    pub header_length: BitVec<u8, Msb0>,
+    pub version: BitVec<u8, Msb0>,
+    pub ack: BitVec<u8, Msb0>,
+    pub reserved: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§next_header: BitVec<u8, Msb0>§header_length: BitVec<u8, Msb0>§version: BitVec<u8, Msb0>§ack: BitVec<u8, Msb0>§reserved: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for ddm_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ddm_h

source§

fn clone(&self) -> ddm_h

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 Debug for ddm_h

source§

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

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

impl Default for ddm_h

source§

fn default() -> ddm_h

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

impl Header for ddm_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for ddm_h

§

impl Send for ddm_h

§

impl Sync for ddm_h

§

impl Unpin for ddm_h

§

impl UnwindSafe for ddm_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.egress_metadata_t.html b/sidecar_lite/struct.egress_metadata_t.html new file mode 100644 index 00000000..8ae29433 --- /dev/null +++ b/sidecar_lite/struct.egress_metadata_t.html @@ -0,0 +1,98 @@ +egress_metadata_t in sidecar_lite - Rust +
pub struct egress_metadata_t {
+    pub port: BitVec<u8, Msb0>,
+    pub nexthop_v6: BitVec<u8, Msb0>,
+    pub nexthop_v4: BitVec<u8, Msb0>,
+    pub drop: bool,
+    pub broadcast: bool,
+}

Fields§

§port: BitVec<u8, Msb0>§nexthop_v6: BitVec<u8, Msb0>§nexthop_v4: BitVec<u8, Msb0>§drop: bool§broadcast: bool

Trait Implementations§

source§

impl Clone for egress_metadata_t

source§

fn clone(&self) -> egress_metadata_t

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 Debug for egress_metadata_t

source§

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

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

impl Default for egress_metadata_t

source§

fn default() -> egress_metadata_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.ethernet_h.html b/sidecar_lite/struct.ethernet_h.html new file mode 100644 index 00000000..28fbd42a --- /dev/null +++ b/sidecar_lite/struct.ethernet_h.html @@ -0,0 +1,97 @@ +ethernet_h in sidecar_lite - Rust +
pub struct ethernet_h {
+    pub valid: bool,
+    pub dst: BitVec<u8, Msb0>,
+    pub src: BitVec<u8, Msb0>,
+    pub ether_type: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§dst: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§ether_type: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for ethernet_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ethernet_h

source§

fn clone(&self) -> ethernet_h

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 Debug for ethernet_h

source§

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

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

impl Default for ethernet_h

source§

fn default() -> ethernet_h

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

impl Header for ethernet_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.geneve_h.html b/sidecar_lite/struct.geneve_h.html new file mode 100644 index 00000000..112b3e71 --- /dev/null +++ b/sidecar_lite/struct.geneve_h.html @@ -0,0 +1,102 @@ +geneve_h in sidecar_lite - Rust +

Struct sidecar_lite::geneve_h

source ·
pub struct geneve_h {
+    pub valid: bool,
+    pub version: BitVec<u8, Msb0>,
+    pub opt_len: BitVec<u8, Msb0>,
+    pub ctrl: BitVec<u8, Msb0>,
+    pub crit: BitVec<u8, Msb0>,
+    pub reserved: BitVec<u8, Msb0>,
+    pub protocol: BitVec<u8, Msb0>,
+    pub vni: BitVec<u8, Msb0>,
+    pub reserved2: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§version: BitVec<u8, Msb0>§opt_len: BitVec<u8, Msb0>§ctrl: BitVec<u8, Msb0>§crit: BitVec<u8, Msb0>§reserved: BitVec<u8, Msb0>§protocol: BitVec<u8, Msb0>§vni: BitVec<u8, Msb0>§reserved2: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for geneve_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for geneve_h

source§

fn clone(&self) -> geneve_h

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 Debug for geneve_h

source§

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

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

impl Default for geneve_h

source§

fn default() -> geneve_h

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

impl Header for geneve_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.headers_t.html b/sidecar_lite/struct.headers_t.html new file mode 100644 index 00000000..7f94f626 --- /dev/null +++ b/sidecar_lite/struct.headers_t.html @@ -0,0 +1,124 @@ +headers_t in sidecar_lite - Rust +

Struct sidecar_lite::headers_t

source ·
pub struct headers_t {
Show 31 fields + pub ethernet: ethernet_h, + pub sidecar: sidecar_h, + pub arp: arp_h, + pub ipv4: ipv4_h, + pub ipv6: ipv6_h, + pub ddm: ddm_h, + pub ddm0: ddm_element_t, + pub ddm1: ddm_element_t, + pub ddm2: ddm_element_t, + pub ddm3: ddm_element_t, + pub ddm4: ddm_element_t, + pub ddm5: ddm_element_t, + pub ddm6: ddm_element_t, + pub ddm7: ddm_element_t, + pub ddm8: ddm_element_t, + pub ddm9: ddm_element_t, + pub ddm10: ddm_element_t, + pub ddm11: ddm_element_t, + pub ddm12: ddm_element_t, + pub ddm13: ddm_element_t, + pub ddm14: ddm_element_t, + pub ddm15: ddm_element_t, + pub icmp: icmp_h, + pub tcp: tcp_h, + pub udp: udp_h, + pub geneve: geneve_h, + pub inner_eth: ethernet_h, + pub inner_ipv4: ipv4_h, + pub inner_ipv6: ipv6_h, + pub inner_tcp: tcp_h, + pub inner_udp: udp_h, +
}

Fields§

§ethernet: ethernet_h§sidecar: sidecar_h§arp: arp_h§ipv4: ipv4_h§ipv6: ipv6_h§ddm: ddm_h§ddm0: ddm_element_t§ddm1: ddm_element_t§ddm2: ddm_element_t§ddm3: ddm_element_t§ddm4: ddm_element_t§ddm5: ddm_element_t§ddm6: ddm_element_t§ddm7: ddm_element_t§ddm8: ddm_element_t§ddm9: ddm_element_t§ddm10: ddm_element_t§ddm11: ddm_element_t§ddm12: ddm_element_t§ddm13: ddm_element_t§ddm14: ddm_element_t§ddm15: ddm_element_t§icmp: icmp_h§tcp: tcp_h§udp: udp_h§geneve: geneve_h§inner_eth: ethernet_h§inner_ipv4: ipv4_h§inner_ipv6: ipv6_h§inner_tcp: tcp_h§inner_udp: udp_h

Trait Implementations§

source§

impl Clone for headers_t

source§

fn clone(&self) -> headers_t

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 Debug for headers_t

source§

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

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

impl Default for headers_t

source§

fn default() -> headers_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.icmp_h.html b/sidecar_lite/struct.icmp_h.html new file mode 100644 index 00000000..cd98c34a --- /dev/null +++ b/sidecar_lite/struct.icmp_h.html @@ -0,0 +1,98 @@ +icmp_h in sidecar_lite - Rust +

Struct sidecar_lite::icmp_h

source ·
pub struct icmp_h {
+    pub valid: bool,
+    pub typ: BitVec<u8, Msb0>,
+    pub code: BitVec<u8, Msb0>,
+    pub hdr_checksum: BitVec<u8, Msb0>,
+    pub data: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§typ: BitVec<u8, Msb0>§code: BitVec<u8, Msb0>§hdr_checksum: BitVec<u8, Msb0>§data: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for icmp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for icmp_h

source§

fn clone(&self) -> icmp_h

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 Debug for icmp_h

source§

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

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

impl Default for icmp_h

source§

fn default() -> icmp_h

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

impl Header for icmp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.ingress_metadata_t.html b/sidecar_lite/struct.ingress_metadata_t.html new file mode 100644 index 00000000..a7ca3cbf --- /dev/null +++ b/sidecar_lite/struct.ingress_metadata_t.html @@ -0,0 +1,97 @@ +ingress_metadata_t in sidecar_lite - Rust +
pub struct ingress_metadata_t {
+    pub port: BitVec<u8, Msb0>,
+    pub nat: bool,
+    pub nat_id: BitVec<u8, Msb0>,
+    pub drop: bool,
+}

Fields§

§port: BitVec<u8, Msb0>§nat: bool§nat_id: BitVec<u8, Msb0>§drop: bool

Trait Implementations§

source§

impl Clone for ingress_metadata_t

source§

fn clone(&self) -> ingress_metadata_t

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 Debug for ingress_metadata_t

source§

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

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

impl Default for ingress_metadata_t

source§

fn default() -> ingress_metadata_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.ipv4_h.html b/sidecar_lite/struct.ipv4_h.html new file mode 100644 index 00000000..4fe9aba5 --- /dev/null +++ b/sidecar_lite/struct.ipv4_h.html @@ -0,0 +1,106 @@ +ipv4_h in sidecar_lite - Rust +

Struct sidecar_lite::ipv4_h

source ·
pub struct ipv4_h {
Show 13 fields + pub valid: bool, + pub version: BitVec<u8, Msb0>, + pub ihl: BitVec<u8, Msb0>, + pub diffserv: BitVec<u8, Msb0>, + pub total_len: BitVec<u8, Msb0>, + pub identification: BitVec<u8, Msb0>, + pub flags: BitVec<u8, Msb0>, + pub frag_offset: BitVec<u8, Msb0>, + pub ttl: BitVec<u8, Msb0>, + pub protocol: BitVec<u8, Msb0>, + pub hdr_checksum: BitVec<u8, Msb0>, + pub src: BitVec<u8, Msb0>, + pub dst: BitVec<u8, Msb0>, +
}

Fields§

§valid: bool§version: BitVec<u8, Msb0>§ihl: BitVec<u8, Msb0>§diffserv: BitVec<u8, Msb0>§total_len: BitVec<u8, Msb0>§identification: BitVec<u8, Msb0>§flags: BitVec<u8, Msb0>§frag_offset: BitVec<u8, Msb0>§ttl: BitVec<u8, Msb0>§protocol: BitVec<u8, Msb0>§hdr_checksum: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§dst: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for ipv4_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ipv4_h

source§

fn clone(&self) -> ipv4_h

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 Debug for ipv4_h

source§

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

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

impl Default for ipv4_h

source§

fn default() -> ipv4_h

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

impl Header for ipv4_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.ipv6_h.html b/sidecar_lite/struct.ipv6_h.html new file mode 100644 index 00000000..a06f943a --- /dev/null +++ b/sidecar_lite/struct.ipv6_h.html @@ -0,0 +1,102 @@ +ipv6_h in sidecar_lite - Rust +

Struct sidecar_lite::ipv6_h

source ·
pub struct ipv6_h {
+    pub valid: bool,
+    pub version: BitVec<u8, Msb0>,
+    pub traffic_class: BitVec<u8, Msb0>,
+    pub flow_label: BitVec<u8, Msb0>,
+    pub payload_len: BitVec<u8, Msb0>,
+    pub next_hdr: BitVec<u8, Msb0>,
+    pub hop_limit: BitVec<u8, Msb0>,
+    pub src: BitVec<u8, Msb0>,
+    pub dst: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§version: BitVec<u8, Msb0>§traffic_class: BitVec<u8, Msb0>§flow_label: BitVec<u8, Msb0>§payload_len: BitVec<u8, Msb0>§next_hdr: BitVec<u8, Msb0>§hop_limit: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§dst: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for ipv6_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ipv6_h

source§

fn clone(&self) -> ipv6_h

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 Debug for ipv6_h

source§

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

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

impl Default for ipv6_h

source§

fn default() -> ipv6_h

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

impl Header for ipv6_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.main_pipeline.html b/sidecar_lite/struct.main_pipeline.html new file mode 100644 index 00000000..493e3342 --- /dev/null +++ b/sidecar_lite/struct.main_pipeline.html @@ -0,0 +1,217 @@ +main_pipeline in sidecar_lite - Rust +
pub struct main_pipeline {
Show 15 fields + pub ingress_local_local_v6: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>, + pub ingress_local_local_v4: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>, + pub ingress_router_router_v6: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, + pub ingress_router_router_v4: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, + pub ingress_nat_nat_v4: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, + pub ingress_nat_nat_v6: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, + pub ingress_nat_nat_icmp_v6: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, + pub ingress_nat_nat_icmp_v4: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, + pub ingress_resolver_resolver_v4: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, + pub ingress_resolver_resolver_v6: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, + pub ingress_mac_mac_rewrite: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, + pub ingress_pxarp_proxy_arp: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, + pub parse: fn(pkt: &mut packet_in<'_>, hdr: &mut headers_t, ingress: &mut ingress_metadata_t) -> bool, + pub ingress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t, local_local_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>, local_local_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>, router_router_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, router_router_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, nat_nat_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, nat_nat_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, nat_nat_icmp_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, nat_nat_icmp_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, resolver_resolver_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, resolver_resolver_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, mac_mac_rewrite: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, pxarp_proxy_arp: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>), + pub egress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t), + /* private fields */ +
}

Fields§

§ingress_local_local_v6: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>§ingress_local_local_v4: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>§ingress_router_router_v6: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>§ingress_router_router_v4: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>§ingress_nat_nat_v4: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>§ingress_nat_nat_v6: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>§ingress_nat_nat_icmp_v6: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>§ingress_nat_nat_icmp_v4: Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>§ingress_resolver_resolver_v4: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>§ingress_resolver_resolver_v6: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>§ingress_mac_mac_rewrite: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>§ingress_pxarp_proxy_arp: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>§parse: fn(pkt: &mut packet_in<'_>, hdr: &mut headers_t, ingress: &mut ingress_metadata_t) -> bool§ingress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t, local_local_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>, local_local_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut bool)>>, router_router_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, router_router_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>, nat_nat_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, nat_nat_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, nat_nat_icmp_v6: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, nat_nat_icmp_v4: &Table<2usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t, &Checksum)>>, resolver_resolver_v4: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, resolver_resolver_v6: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, mac_mac_rewrite: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>, pxarp_proxy_arp: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut ingress_metadata_t, &mut egress_metadata_t)>>)§egress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t)

Implementations§

source§

impl main_pipeline

source

pub fn new(radix: u16) -> Self

source

pub fn add_ingress_local_local_v6_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_local_local_v6_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_local_local_v6_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_local_local_v4_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_local_local_v4_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_local_local_v4_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_router_router_v6_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_router_router_v6_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_router_router_v6_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_router_router_v4_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_router_router_v4_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_router_router_v4_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_nat_nat_v4_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_nat_nat_v4_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_nat_nat_v4_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_nat_nat_v6_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_nat_nat_v6_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_nat_nat_v6_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_nat_nat_icmp_v6_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_nat_nat_icmp_v6_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_nat_nat_icmp_v6_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_nat_nat_icmp_v4_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_nat_nat_icmp_v4_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_nat_nat_icmp_v4_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_resolver_resolver_v4_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_resolver_resolver_v4_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_resolver_resolver_v4_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_resolver_resolver_v6_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_resolver_resolver_v6_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_resolver_resolver_v6_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_mac_mac_rewrite_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_mac_mac_rewrite_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_mac_mac_rewrite_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_pxarp_proxy_arp_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_pxarp_proxy_arp_entry<'a>( + &mut self, + keyset_data: &'a [u8] +)

source

pub fn get_ingress_pxarp_proxy_arp_entries(&self) -> Vec<TableEntry>

Trait Implementations§

source§

impl Pipeline for main_pipeline

source§

fn process_packet<'a>( + &mut self, + port: u16, + pkt: &mut packet_in<'a> +) -> Vec<(packet_out<'a>, u16)>

Process an input packet and produce a set of output packets. Normally +there will be a single output packet. However, if the pipeline sets +egress_metadata_t.broadcast there may be multiple output packets.
source§

fn add_table_entry( + &mut self, + table_id: &str, + action_id: &str, + keyset_data: &[u8], + parameter_data: &[u8], + priority: u32 +)

Add an entry to a table identified by table_id.
source§

fn remove_table_entry(&mut self, table_id: &str, keyset_data: &[u8])

Remove an entry from a table identified by table_id.
source§

fn get_table_entries(&self, table_id: &str) -> Option<Vec<TableEntry>>

Get all the entries in a table.
source§

fn get_table_ids(&self) -> Vec<&str>

Get a list of table ids
source§

impl Send for main_pipeline

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.sidecar_h.html b/sidecar_lite/struct.sidecar_h.html new file mode 100644 index 00000000..e5104db9 --- /dev/null +++ b/sidecar_lite/struct.sidecar_h.html @@ -0,0 +1,99 @@ +sidecar_h in sidecar_lite - Rust +

Struct sidecar_lite::sidecar_h

source ·
pub struct sidecar_h {
+    pub valid: bool,
+    pub sc_code: BitVec<u8, Msb0>,
+    pub sc_ingress: BitVec<u8, Msb0>,
+    pub sc_egress: BitVec<u8, Msb0>,
+    pub sc_ether_type: BitVec<u8, Msb0>,
+    pub sc_payload: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§sc_code: BitVec<u8, Msb0>§sc_ingress: BitVec<u8, Msb0>§sc_egress: BitVec<u8, Msb0>§sc_ether_type: BitVec<u8, Msb0>§sc_payload: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for sidecar_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for sidecar_h

source§

fn clone(&self) -> sidecar_h

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 Debug for sidecar_h

source§

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

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

impl Default for sidecar_h

source§

fn default() -> sidecar_h

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

impl Header for sidecar_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.tcp_h.html b/sidecar_lite/struct.tcp_h.html new file mode 100644 index 00000000..ee53761a --- /dev/null +++ b/sidecar_lite/struct.tcp_h.html @@ -0,0 +1,104 @@ +tcp_h in sidecar_lite - Rust +

Struct sidecar_lite::tcp_h

source ·
pub struct tcp_h {
+    pub valid: bool,
+    pub src_port: BitVec<u8, Msb0>,
+    pub dst_port: BitVec<u8, Msb0>,
+    pub seq_no: BitVec<u8, Msb0>,
+    pub ack_no: BitVec<u8, Msb0>,
+    pub data_offset: BitVec<u8, Msb0>,
+    pub res: BitVec<u8, Msb0>,
+    pub flags: BitVec<u8, Msb0>,
+    pub window: BitVec<u8, Msb0>,
+    pub checksum: BitVec<u8, Msb0>,
+    pub urgent_ptr: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§src_port: BitVec<u8, Msb0>§dst_port: BitVec<u8, Msb0>§seq_no: BitVec<u8, Msb0>§ack_no: BitVec<u8, Msb0>§data_offset: BitVec<u8, Msb0>§res: BitVec<u8, Msb0>§flags: BitVec<u8, Msb0>§window: BitVec<u8, Msb0>§checksum: BitVec<u8, Msb0>§urgent_ptr: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for tcp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for tcp_h

source§

fn clone(&self) -> tcp_h

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 Debug for tcp_h

source§

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

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

impl Default for tcp_h

source§

fn default() -> tcp_h

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

impl Header for tcp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for tcp_h

§

impl Send for tcp_h

§

impl Sync for tcp_h

§

impl Unpin for tcp_h

§

impl UnwindSafe for tcp_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.udp_h.html b/sidecar_lite/struct.udp_h.html new file mode 100644 index 00000000..90ba0f01 --- /dev/null +++ b/sidecar_lite/struct.udp_h.html @@ -0,0 +1,98 @@ +udp_h in sidecar_lite - Rust +

Struct sidecar_lite::udp_h

source ·
pub struct udp_h {
+    pub valid: bool,
+    pub src_port: BitVec<u8, Msb0>,
+    pub dst_port: BitVec<u8, Msb0>,
+    pub len: BitVec<u8, Msb0>,
+    pub checksum: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§src_port: BitVec<u8, Msb0>§dst_port: BitVec<u8, Msb0>§len: BitVec<u8, Msb0>§checksum: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for udp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for udp_h

source§

fn clone(&self) -> udp_h

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 Debug for udp_h

source§

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

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

impl Default for udp_h

source§

fn default() -> udp_h

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

impl Header for udp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for udp_h

§

impl Send for udp_h

§

impl Sync for udp_h

§

impl Unpin for udp_h

§

impl UnwindSafe for udp_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/sidecar_lite/struct.vlan_h.html b/sidecar_lite/struct.vlan_h.html new file mode 100644 index 00000000..256e3620 --- /dev/null +++ b/sidecar_lite/struct.vlan_h.html @@ -0,0 +1,97 @@ +vlan_h in sidecar_lite - Rust +

Struct sidecar_lite::vlan_h

source ·
pub struct vlan_h {
+    pub valid: bool,
+    pub pcp: BitVec<u8, Msb0>,
+    pub dei: BitVec<u8, Msb0>,
+    pub vid: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§pcp: BitVec<u8, Msb0>§dei: BitVec<u8, Msb0>§vid: BitVec<u8, Msb0>

Trait Implementations§

source§

impl Checksum for vlan_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for vlan_h

source§

fn clone(&self) -> vlan_h

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 Debug for vlan_h

source§

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

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

impl Default for vlan_h

source§

fn default() -> vlan_h

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

impl Header for vlan_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
\ No newline at end of file diff --git a/src-files.js b/src-files.js new file mode 100644 index 00000000..44a8a5df --- /dev/null +++ b/src-files.js @@ -0,0 +1,14 @@ +var srcIndex = new Map(JSON.parse('[\ +["hello_world",["",[],["hello-world.rs"]]],\ +["p4",["",[],["ast.rs","check.rs","error.rs","hlir.rs","lexer.rs","lib.rs","parser.rs","preprocessor.rs","util.rs"]]],\ +["p4_macro",["",[],["lib.rs"]]],\ +["p4_macro_test",["",[],["main.rs"]]],\ +["p4_rust",["",[],["control.rs","expression.rs","header.rs","lib.rs","p4struct.rs","parser.rs","pipeline.rs","statement.rs"]]],\ +["p4rs",["",[],["bitmath.rs","checksum.rs","error.rs","externs.rs","lib.rs","table.rs"]]],\ +["sidecar_lite",["",[],["lib.rs"]]],\ +["tests",["",[],["data.rs","lib.rs","packet.rs","softnpu.rs"]]],\ +["vlan_switch",["",[],["vlan-switch.rs"]]],\ +["x4c",["",[],["lib.rs"]]],\ +["x4c_error_codes",["",[],["lib.rs"]]]\ +]')); +createSrcSidebar(); diff --git a/src/hello_world/hello-world.rs.html b/src/hello_world/hello-world.rs.html new file mode 100644 index 00000000..7c4b7119 --- /dev/null +++ b/src/hello_world/hello-world.rs.html @@ -0,0 +1,51 @@ +hello-world.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+
#![allow(clippy::needless_update)]
+use tests::expect_frames;
+use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+
+p4_macro::use_p4!(
+    p4 = "book/code/src/bin/hello-world.p4",
+    pipeline_name = "hello"
+);
+
+fn main() -> Result<(), anyhow::Error> {
+    let mut npu = SoftNpu::new(2, main_pipeline::new(2), false);
+    let phy1 = npu.phy(0);
+    let phy2 = npu.phy(1);
+
+    npu.run();
+
+    phy1.send(&[TxFrame::new(phy2.mac, 0, b"hello")])?;
+    expect_frames!(phy2, &[RxFrame::new(phy1.mac, 0, b"hello")]);
+
+    phy2.send(&[TxFrame::new(phy1.mac, 0, b"world")])?;
+    expect_frames!(phy1, &[RxFrame::new(phy2.mac, 0, b"world")]);
+
+    Ok(())
+}
+
\ No newline at end of file diff --git a/src/p4/ast.rs.html b/src/p4/ast.rs.html new file mode 100644 index 00000000..ae6fce62 --- /dev/null +++ b/src/p4/ast.rs.html @@ -0,0 +1,4905 @@ +ast.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+1869
+1870
+1871
+1872
+1873
+1874
+1875
+1876
+1877
+1878
+1879
+1880
+1881
+1882
+1883
+1884
+1885
+1886
+1887
+1888
+1889
+1890
+1891
+1892
+1893
+1894
+1895
+1896
+1897
+1898
+1899
+1900
+1901
+1902
+1903
+1904
+1905
+1906
+1907
+1908
+1909
+1910
+1911
+1912
+1913
+1914
+1915
+1916
+1917
+1918
+1919
+1920
+1921
+1922
+1923
+1924
+1925
+1926
+1927
+1928
+1929
+1930
+1931
+1932
+1933
+1934
+1935
+1936
+1937
+1938
+1939
+1940
+1941
+1942
+1943
+1944
+1945
+1946
+1947
+1948
+1949
+1950
+1951
+1952
+1953
+1954
+1955
+1956
+1957
+1958
+1959
+1960
+1961
+1962
+1963
+1964
+1965
+1966
+1967
+1968
+1969
+1970
+1971
+1972
+1973
+1974
+1975
+1976
+1977
+1978
+1979
+1980
+1981
+1982
+1983
+1984
+1985
+1986
+1987
+1988
+1989
+1990
+1991
+1992
+1993
+1994
+1995
+1996
+1997
+1998
+1999
+2000
+2001
+2002
+2003
+2004
+2005
+2006
+2007
+2008
+2009
+2010
+2011
+2012
+2013
+2014
+2015
+2016
+2017
+2018
+2019
+2020
+2021
+2022
+2023
+2024
+2025
+2026
+2027
+2028
+2029
+2030
+2031
+2032
+2033
+2034
+2035
+2036
+2037
+2038
+2039
+2040
+2041
+2042
+2043
+2044
+2045
+2046
+2047
+2048
+2049
+2050
+2051
+2052
+2053
+2054
+2055
+2056
+2057
+2058
+2059
+2060
+2061
+2062
+2063
+2064
+2065
+2066
+2067
+2068
+2069
+2070
+2071
+2072
+2073
+2074
+2075
+2076
+2077
+2078
+2079
+2080
+2081
+2082
+2083
+2084
+2085
+2086
+2087
+2088
+2089
+2090
+2091
+2092
+2093
+2094
+2095
+2096
+2097
+2098
+2099
+2100
+2101
+2102
+2103
+2104
+2105
+2106
+2107
+2108
+2109
+2110
+2111
+2112
+2113
+2114
+2115
+2116
+2117
+2118
+2119
+2120
+2121
+2122
+2123
+2124
+2125
+2126
+2127
+2128
+2129
+2130
+2131
+2132
+2133
+2134
+2135
+2136
+2137
+2138
+2139
+2140
+2141
+2142
+2143
+2144
+2145
+2146
+2147
+2148
+2149
+2150
+2151
+2152
+2153
+2154
+2155
+2156
+2157
+2158
+2159
+2160
+2161
+2162
+2163
+2164
+2165
+2166
+2167
+2168
+2169
+2170
+2171
+2172
+2173
+2174
+2175
+2176
+2177
+2178
+2179
+2180
+2181
+2182
+2183
+2184
+2185
+2186
+2187
+2188
+2189
+2190
+2191
+2192
+2193
+2194
+2195
+2196
+2197
+2198
+2199
+2200
+2201
+2202
+2203
+2204
+2205
+2206
+2207
+2208
+2209
+2210
+2211
+2212
+2213
+2214
+2215
+2216
+2217
+2218
+2219
+2220
+2221
+2222
+2223
+2224
+2225
+2226
+2227
+2228
+2229
+2230
+2231
+2232
+2233
+2234
+2235
+2236
+2237
+2238
+2239
+2240
+2241
+2242
+2243
+2244
+2245
+2246
+2247
+2248
+2249
+2250
+2251
+2252
+2253
+2254
+2255
+2256
+2257
+2258
+2259
+2260
+2261
+2262
+2263
+2264
+2265
+2266
+2267
+2268
+2269
+2270
+2271
+2272
+2273
+2274
+2275
+2276
+2277
+2278
+2279
+2280
+2281
+2282
+2283
+2284
+2285
+2286
+2287
+2288
+2289
+2290
+2291
+2292
+2293
+2294
+2295
+2296
+2297
+2298
+2299
+2300
+2301
+2302
+2303
+2304
+2305
+2306
+2307
+2308
+2309
+2310
+2311
+2312
+2313
+2314
+2315
+2316
+2317
+2318
+2319
+2320
+2321
+2322
+2323
+2324
+2325
+2326
+2327
+2328
+2329
+2330
+2331
+2332
+2333
+2334
+2335
+2336
+2337
+2338
+2339
+2340
+2341
+2342
+2343
+2344
+2345
+2346
+2347
+2348
+2349
+2350
+2351
+2352
+2353
+2354
+2355
+2356
+2357
+2358
+2359
+2360
+2361
+2362
+2363
+2364
+2365
+2366
+2367
+2368
+2369
+2370
+2371
+2372
+2373
+2374
+2375
+2376
+2377
+2378
+2379
+2380
+2381
+2382
+2383
+2384
+2385
+2386
+2387
+2388
+2389
+2390
+2391
+2392
+2393
+2394
+2395
+2396
+2397
+2398
+2399
+2400
+2401
+2402
+2403
+2404
+2405
+2406
+2407
+2408
+2409
+2410
+2411
+2412
+2413
+2414
+2415
+2416
+2417
+2418
+2419
+2420
+2421
+2422
+2423
+2424
+2425
+2426
+2427
+2428
+2429
+2430
+2431
+2432
+2433
+2434
+2435
+2436
+2437
+2438
+2439
+2440
+2441
+2442
+2443
+2444
+2445
+2446
+2447
+2448
+2449
+2450
+2451
+
// Copyright 2022 Oxide Computer Company
+
+use std::cmp::{Eq, PartialEq};
+use std::collections::HashMap;
+use std::fmt;
+use std::hash::{Hash, Hasher};
+
+use crate::lexer::Token;
+
+#[derive(Debug, Default)]
+pub struct AST {
+    pub constants: Vec<Constant>,
+    pub headers: Vec<Header>,
+    pub structs: Vec<Struct>,
+    pub typedefs: Vec<Typedef>,
+    pub controls: Vec<Control>,
+    pub parsers: Vec<Parser>,
+    pub packages: Vec<Package>,
+    pub package_instance: Option<PackageInstance>,
+    pub externs: Vec<Extern>,
+}
+
+pub enum UserDefinedType<'a> {
+    Struct(&'a Struct),
+    Header(&'a Header),
+    Extern(&'a Extern),
+}
+
+impl AST {
+    pub fn get_struct(&self, name: &str) -> Option<&Struct> {
+        self.structs.iter().find(|&s| s.name == name)
+    }
+
+    pub fn get_header(&self, name: &str) -> Option<&Header> {
+        self.headers.iter().find(|&h| h.name == name)
+    }
+
+    pub fn get_extern(&self, name: &str) -> Option<&Extern> {
+        self.externs.iter().find(|&e| e.name == name)
+    }
+
+    pub fn get_control(&self, name: &str) -> Option<&Control> {
+        self.controls.iter().find(|&c| c.name == name)
+    }
+
+    pub fn get_parser(&self, name: &str) -> Option<&Parser> {
+        self.parsers.iter().find(|&p| p.name == name)
+    }
+
+    pub fn get_user_defined_type(&self, name: &str) -> Option<UserDefinedType> {
+        if let Some(user_struct) = self.get_struct(name) {
+            return Some(UserDefinedType::Struct(user_struct));
+        }
+        if let Some(user_header) = self.get_header(name) {
+            return Some(UserDefinedType::Header(user_header));
+        }
+        if let Some(platform_extern) = self.get_extern(name) {
+            return Some(UserDefinedType::Extern(platform_extern));
+        }
+        None
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        for c in &self.constants {
+            c.accept(v)
+        }
+        for h in &self.headers {
+            h.accept(v);
+        }
+        for s in &self.structs {
+            s.accept(v);
+        }
+        for t in &self.typedefs {
+            t.accept(v);
+        }
+        for c in &self.controls {
+            c.accept(v);
+        }
+        for p in &self.parsers {
+            p.accept(v);
+        }
+        for p in &self.packages {
+            p.accept(v);
+        }
+        for e in &self.externs {
+            e.accept(v);
+        }
+        if let Some(p) = &self.package_instance {
+            p.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        for c in &self.constants {
+            c.accept_mut(v)
+        }
+        for h in &self.headers {
+            h.accept_mut(v);
+        }
+        for s in &self.structs {
+            s.accept_mut(v);
+        }
+        for t in &self.typedefs {
+            t.accept_mut(v);
+        }
+        for c in &self.controls {
+            c.accept_mut(v);
+        }
+        for p in &self.parsers {
+            p.accept_mut(v);
+        }
+        for p in &self.packages {
+            p.accept_mut(v);
+        }
+        for e in &self.externs {
+            e.accept_mut(v);
+        }
+        if let Some(p) = &self.package_instance {
+            p.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        for c in &mut self.constants {
+            c.mut_accept(v)
+        }
+        for h in &mut self.headers {
+            h.mut_accept(v);
+        }
+        for s in &mut self.structs {
+            s.mut_accept(v);
+        }
+        for t in &mut self.typedefs {
+            t.mut_accept(v);
+        }
+        for c in &mut self.controls {
+            c.mut_accept(v);
+        }
+        for p in &mut self.parsers {
+            p.mut_accept(v);
+        }
+        for p in &mut self.packages {
+            p.mut_accept(v);
+        }
+        for e in &mut self.externs {
+            e.mut_accept(v);
+        }
+        if let Some(p) = &mut self.package_instance {
+            p.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        for c in &mut self.constants {
+            c.mut_accept_mut(v)
+        }
+        for h in &mut self.headers {
+            h.mut_accept_mut(v);
+        }
+        for s in &mut self.structs {
+            s.mut_accept_mut(v);
+        }
+        for t in &mut self.typedefs {
+            t.mut_accept_mut(v);
+        }
+        for c in &mut self.controls {
+            c.mut_accept_mut(v);
+        }
+        for p in &mut self.parsers {
+            p.mut_accept_mut(v);
+        }
+        for p in &mut self.packages {
+            p.mut_accept_mut(v);
+        }
+        for e in &mut self.externs {
+            e.mut_accept_mut(v);
+        }
+        if let Some(p) = &mut self.package_instance {
+            p.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct PackageInstance {
+    pub instance_type: String,
+    pub name: String,
+    pub parameters: Vec<String>,
+}
+
+impl PackageInstance {
+    pub fn new(instance_type: String) -> Self {
+        Self {
+            instance_type,
+            name: "".into(),
+            parameters: Vec::new(),
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.package_instance(self);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.package_instance(self);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.package_instance(self);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.package_instance(self);
+    }
+}
+
+#[derive(Debug)]
+pub struct Package {
+    pub name: String,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<PackageParameter>,
+}
+
+impl Package {
+    pub fn new(name: String) -> Self {
+        Self {
+            name,
+            type_parameters: Vec::new(),
+            parameters: Vec::new(),
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.package(self);
+        for p in &self.parameters {
+            p.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.package(self);
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.package(self);
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.package(self);
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug)]
+pub struct PackageParameter {
+    pub type_name: String,
+    pub type_parameters: Vec<String>,
+    pub name: String,
+}
+
+impl PackageParameter {
+    pub fn new(type_name: String) -> Self {
+        Self {
+            type_name,
+            type_parameters: Vec::new(),
+            name: String::new(),
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.package_parameter(self);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.package_parameter(self);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.package_parameter(self);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.package_parameter(self);
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum Type {
+    Bool,
+    Error,
+    Bit(usize),
+    Varbit(usize),
+    Int(usize),
+    String,
+    UserDefined(String),
+    ExternFunction, //TODO actual signature
+    Table,
+    Void,
+    List(Vec<Box<Type>>),
+    State,
+    Action,
+    HeaderMethod,
+}
+
+impl Type {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.typ(self);
+        if let Type::List(types) = self {
+            for t in types {
+                t.accept(v);
+            }
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.typ(self);
+        if let Type::List(types) = self {
+            for t in types {
+                t.accept_mut(v);
+            }
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.typ(self);
+        if let Type::List(types) = self {
+            for t in types {
+                t.mut_accept(v);
+            }
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.typ(self);
+        if let Type::List(types) = self {
+            for t in types {
+                t.mut_accept_mut(v);
+            }
+        }
+    }
+}
+
+impl fmt::Display for Type {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match &self {
+            Type::Bool => write!(f, "bool"),
+            Type::Error => write!(f, "error"),
+            Type::Bit(size) => write!(f, "bit<{}>", size),
+            Type::Varbit(size) => write!(f, "varbit<{}>", size),
+            Type::Int(size) => write!(f, "int<{}>", size),
+            Type::String => write!(f, "string"),
+            Type::UserDefined(name) => write!(f, "{}", name),
+            Type::ExternFunction => write!(f, "extern function"),
+            Type::Table => write!(f, "table"),
+            Type::Void => write!(f, "void"),
+            Type::State => write!(f, "state"),
+            Type::Action => write!(f, "action"),
+            Type::HeaderMethod => write!(f, "header method"),
+            Type::List(elems) => {
+                write!(f, "list<")?;
+                for e in elems {
+                    write!(f, "{},", e)?;
+                }
+                write!(f, ">")
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Typedef {
+    pub ty: Type,
+    pub name: String,
+}
+
+impl Typedef {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.typedef(self);
+        self.ty.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.typedef(self);
+        self.ty.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.typedef(self);
+        self.ty.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.typedef(self);
+        self.ty.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Constant {
+    pub ty: Type,
+    pub name: String,
+    pub initializer: Box<Expression>,
+}
+
+impl Constant {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.constant(self);
+        self.ty.accept(v);
+        self.initializer.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.constant(self);
+        self.ty.accept_mut(v);
+        self.initializer.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.constant(self);
+        self.ty.mut_accept(v);
+        self.initializer.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.constant(self);
+        self.ty.mut_accept_mut(v);
+        self.initializer.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Variable {
+    pub ty: Type,
+    pub name: String,
+    pub initializer: Option<Box<Expression>>,
+    pub parameters: Vec<ControlParameter>,
+    pub token: Token,
+}
+
+impl Variable {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.variable(self);
+        self.ty.accept(v);
+        if let Some(init) = &self.initializer {
+            init.accept(v);
+        }
+        for p in &self.parameters {
+            p.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.variable(self);
+        self.ty.accept_mut(v);
+        if let Some(init) = &self.initializer {
+            init.accept_mut(v);
+        }
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.variable(self);
+        self.ty.mut_accept(v);
+        if let Some(init) = &mut self.initializer {
+            init.mut_accept(v);
+        }
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.variable(self);
+        self.ty.mut_accept_mut(v);
+        if let Some(init) = &mut self.initializer {
+            init.mut_accept_mut(v);
+        }
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Expression {
+    pub token: Token,
+    pub kind: ExpressionKind,
+}
+
+impl Expression {
+    pub fn new(token: Token, kind: ExpressionKind) -> Box<Self> {
+        Box::new(Self { token, kind })
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.expression(self);
+        match &self.kind {
+            ExpressionKind::Lvalue(lv) => lv.accept(v),
+            ExpressionKind::Binary(lhs, op, rhs) => {
+                lhs.accept(v);
+                op.accept(v);
+                rhs.accept(v);
+            }
+            ExpressionKind::Index(lval, xpr) => {
+                lval.accept(v);
+                xpr.accept(v);
+            }
+            ExpressionKind::Slice(begin, end) => {
+                begin.accept(v);
+                end.accept(v);
+            }
+            ExpressionKind::Call(call) => call.accept(v),
+            ExpressionKind::List(xprs) => {
+                for xp in xprs {
+                    xp.accept(v);
+                }
+            }
+            _ => {} // covered by top level visit
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.expression(self);
+        match &self.kind {
+            ExpressionKind::Lvalue(lv) => lv.accept_mut(v),
+            ExpressionKind::Binary(lhs, op, rhs) => {
+                lhs.accept_mut(v);
+                op.accept_mut(v);
+                rhs.accept_mut(v);
+            }
+            ExpressionKind::Index(lval, xpr) => {
+                lval.accept_mut(v);
+                xpr.accept_mut(v);
+            }
+            ExpressionKind::Slice(begin, end) => {
+                begin.accept_mut(v);
+                end.accept_mut(v);
+            }
+            ExpressionKind::Call(call) => call.accept_mut(v),
+            ExpressionKind::List(xprs) => {
+                for xp in xprs {
+                    xp.accept_mut(v);
+                }
+            }
+            _ => {} // covered by top level visit
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.expression(self);
+        match &mut self.kind {
+            ExpressionKind::Lvalue(lv) => lv.mut_accept(v),
+            ExpressionKind::Binary(lhs, op, rhs) => {
+                lhs.mut_accept(v);
+                op.mut_accept(v);
+                rhs.mut_accept(v);
+            }
+            ExpressionKind::Index(lval, xpr) => {
+                lval.mut_accept(v);
+                xpr.mut_accept(v);
+            }
+            ExpressionKind::Slice(begin, end) => {
+                begin.mut_accept(v);
+                end.mut_accept(v);
+            }
+            ExpressionKind::Call(call) => call.mut_accept(v),
+            ExpressionKind::List(xprs) => {
+                for xp in xprs {
+                    xp.mut_accept(v);
+                }
+            }
+            _ => {} // covered by top level visit
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.expression(self);
+        match &mut self.kind {
+            ExpressionKind::Lvalue(lv) => lv.mut_accept_mut(v),
+            ExpressionKind::Binary(lhs, op, rhs) => {
+                lhs.mut_accept_mut(v);
+                op.mut_accept_mut(v);
+                rhs.mut_accept_mut(v);
+            }
+            ExpressionKind::Index(lval, xpr) => {
+                lval.mut_accept_mut(v);
+                xpr.mut_accept_mut(v);
+            }
+            ExpressionKind::Slice(begin, end) => {
+                begin.mut_accept_mut(v);
+                end.mut_accept_mut(v);
+            }
+            ExpressionKind::Call(call) => call.mut_accept_mut(v),
+            ExpressionKind::List(xprs) => {
+                for xp in xprs {
+                    xp.mut_accept_mut(v);
+                }
+            }
+            _ => {} // covered by top level visit
+        }
+    }
+}
+
+impl Hash for Expression {
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        self.token.hash(state);
+    }
+}
+
+impl PartialEq for Expression {
+    fn eq(&self, other: &Self) -> bool {
+        self.token == other.token
+    }
+}
+
+impl Eq for Expression {}
+
+#[derive(Debug, Clone)]
+pub enum ExpressionKind {
+    BoolLit(bool),
+    IntegerLit(i128),
+    BitLit(u16, u128),
+    SignedLit(u16, i128),
+    Lvalue(Lvalue),
+    Binary(Box<Expression>, BinOp, Box<Expression>),
+    Index(Lvalue, Box<Expression>),
+    Slice(Box<Expression>, Box<Expression>),
+    Call(Call),
+    List(Vec<Box<Expression>>),
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum BinOp {
+    Add,
+    Subtract,
+    Mod,
+    Geq,
+    Gt,
+    Leq,
+    Lt,
+    Eq,
+    Mask,
+    NotEq,
+    BitAnd,
+    BitOr,
+    Xor,
+}
+
+impl BinOp {
+    pub fn english_verb(&self) -> &str {
+        match self {
+            BinOp::Add => "add",
+            BinOp::Subtract => "subtract",
+            BinOp::Mod => "mod",
+            BinOp::Geq | BinOp::Gt | BinOp::Leq | BinOp::Lt | BinOp::Eq => {
+                "compare"
+            }
+            BinOp::Mask => "mask",
+            BinOp::NotEq => "not equal",
+            BinOp::BitAnd => "bitwise and",
+            BinOp::BitOr => "bitwise or",
+            BinOp::Xor => "xor",
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.binop(self);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.binop(self);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.binop(self);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.binop(self);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Header {
+    pub name: String,
+    pub members: Vec<HeaderMember>,
+}
+
+impl Header {
+    pub fn new(name: String) -> Self {
+        Header {
+            name,
+            members: Vec::new(),
+        }
+    }
+    pub fn names(&self) -> HashMap<String, NameInfo> {
+        let mut names = HashMap::new();
+        names.insert(
+            "setValid".into(),
+            NameInfo {
+                ty: Type::HeaderMethod,
+                decl: DeclarationInfo::Method,
+            },
+        );
+        names.insert(
+            "setInvalid".into(),
+            NameInfo {
+                ty: Type::HeaderMethod,
+                decl: DeclarationInfo::Method,
+            },
+        );
+        names.insert(
+            "isValid".into(),
+            NameInfo {
+                ty: Type::HeaderMethod,
+                decl: DeclarationInfo::Method,
+            },
+        );
+        for p in &self.members {
+            names.insert(
+                p.name.clone(),
+                NameInfo {
+                    ty: p.ty.clone(),
+                    decl: DeclarationInfo::HeaderMember,
+                },
+            );
+        }
+        names
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.header(self);
+        for m in &self.members {
+            m.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.header(self);
+        for m in &self.members {
+            m.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.header(self);
+        for m in &mut self.members {
+            m.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.header(self);
+        for m in &mut self.members {
+            m.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct HeaderMember {
+    pub ty: Type,
+    pub name: String,
+    pub token: Token,
+}
+
+impl HeaderMember {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.header_member(self);
+        self.ty.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.header_member(self);
+        self.ty.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.header_member(self);
+        self.ty.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.header_member(self);
+        self.ty.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Struct {
+    pub name: String,
+    pub members: Vec<StructMember>,
+}
+
+impl Struct {
+    pub fn new(name: String) -> Self {
+        Struct {
+            name,
+            members: Vec::new(),
+        }
+    }
+    pub fn names(&self) -> HashMap<String, NameInfo> {
+        let mut names = HashMap::new();
+        for p in &self.members {
+            names.insert(
+                p.name.clone(),
+                NameInfo {
+                    ty: p.ty.clone(),
+                    decl: DeclarationInfo::StructMember,
+                },
+            );
+        }
+        names
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.p4struct(self);
+        for m in &self.members {
+            m.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.p4struct(self);
+        for m in &self.members {
+            m.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.p4struct(self);
+        for m in &mut self.members {
+            m.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.p4struct(self);
+        for m in &mut self.members {
+            m.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct StructMember {
+    pub ty: Type,
+    pub name: String,
+    pub token: Token,
+}
+
+impl StructMember {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.struct_member(self);
+        self.ty.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.struct_member(self);
+        self.ty.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.struct_member(self);
+        self.ty.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.struct_member(self);
+        self.ty.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Control {
+    pub name: String,
+    pub variables: Vec<Variable>,
+    pub constants: Vec<Constant>,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<ControlParameter>,
+    pub actions: Vec<Action>,
+    pub tables: Vec<Table>,
+    pub apply: StatementBlock,
+}
+
+impl Control {
+    pub fn new(name: String) -> Self {
+        Self {
+            name,
+            variables: Vec::new(),
+            constants: Vec::new(),
+            type_parameters: Vec::new(),
+            parameters: Vec::new(),
+            actions: Vec::new(),
+            tables: Vec::new(),
+            apply: StatementBlock::default(),
+        }
+    }
+
+    pub fn get_parameter(&self, name: &str) -> Option<&ControlParameter> {
+        self.parameters.iter().find(|&p| p.name == name)
+    }
+
+    pub fn get_action(&self, name: &str) -> Option<&Action> {
+        self.actions.iter().find(|&a| a.name == name)
+    }
+
+    pub fn get_table(&self, name: &str) -> Option<&Table> {
+        self.tables.iter().find(|&t| t.name == name)
+    }
+
+    /// Return all the tables in this control block, recursively expanding local
+    /// control block variables and including their tables. In the returned
+    /// vector, the table in the second element of the tuple belongs to the
+    /// control in the first element.
+    pub fn tables<'a>(
+        &'a self,
+        ast: &'a AST,
+    ) -> Vec<(Vec<(String, &Control)>, &Table)> {
+        self.tables_rec(ast, String::new(), Vec::new())
+    }
+
+    fn tables_rec<'a>(
+        &'a self,
+        ast: &'a AST,
+        name: String,
+        mut chain: Vec<(String, &'a Control)>,
+    ) -> Vec<(Vec<(String, &Control)>, &Table)> {
+        let mut result = Vec::new();
+        chain.push((name, self));
+        for table in &self.tables {
+            result.push((chain.clone(), table));
+        }
+        for v in &self.variables {
+            if let Type::UserDefined(typename) = &v.ty {
+                if let Some(control_inst) = ast.get_control(typename) {
+                    result.extend_from_slice(&control_inst.tables_rec(
+                        ast,
+                        v.name.clone(),
+                        chain.clone(),
+                    ));
+                }
+            }
+        }
+        result
+    }
+
+    pub fn is_type_parameter(&self, name: &str) -> bool {
+        for t in &self.type_parameters {
+            if t == name {
+                return true;
+            }
+        }
+        false
+    }
+
+    pub fn names(&self) -> HashMap<String, NameInfo> {
+        let mut names = HashMap::new();
+        for p in &self.parameters {
+            names.insert(
+                p.name.clone(),
+                NameInfo {
+                    ty: p.ty.clone(),
+                    decl: DeclarationInfo::Parameter(p.direction),
+                },
+            );
+        }
+        for t in &self.tables {
+            names.insert(
+                t.name.clone(),
+                NameInfo {
+                    ty: Type::Table,
+                    decl: DeclarationInfo::ControlTable,
+                },
+            );
+        }
+        for v in &self.variables {
+            names.insert(
+                v.name.clone(),
+                NameInfo {
+                    ty: v.ty.clone(),
+                    decl: DeclarationInfo::ControlMember,
+                },
+            );
+        }
+        for c in &self.constants {
+            names.insert(
+                c.name.clone(),
+                NameInfo {
+                    ty: c.ty.clone(),
+                    decl: DeclarationInfo::ControlMember,
+                },
+            );
+        }
+        for a in &self.actions {
+            names.insert(
+                a.name.clone(),
+                NameInfo {
+                    ty: Type::Action,
+                    decl: DeclarationInfo::Action,
+                },
+            );
+        }
+        names
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.control(self);
+        for var in &self.variables {
+            var.accept(v);
+        }
+        for c in &self.constants {
+            c.accept(v);
+        }
+        for p in &self.parameters {
+            p.accept(v);
+        }
+        for a in &self.actions {
+            a.accept(v);
+        }
+        for t in &self.tables {
+            t.accept(v);
+        }
+        for s in &self.apply.statements {
+            s.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.control(self);
+        for var in &self.variables {
+            var.accept_mut(v);
+        }
+        for c in &self.constants {
+            c.accept_mut(v);
+        }
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+        for a in &self.actions {
+            a.accept_mut(v);
+        }
+        for t in &self.tables {
+            t.accept_mut(v);
+        }
+        for s in &self.apply.statements {
+            s.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.control(self);
+        for var in &mut self.variables {
+            var.mut_accept(v);
+        }
+        for c in &mut self.constants {
+            c.mut_accept(v);
+        }
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+        for a in &mut self.actions {
+            a.mut_accept(v);
+        }
+        for t in &mut self.tables {
+            t.mut_accept(v);
+        }
+        for s in &mut self.apply.statements {
+            s.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.control(self);
+        for var in &mut self.variables {
+            var.mut_accept_mut(v);
+        }
+        for c in &mut self.constants {
+            c.mut_accept_mut(v);
+        }
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+        for a in &mut self.actions {
+            a.mut_accept_mut(v);
+        }
+        for t in &mut self.tables {
+            t.mut_accept_mut(v);
+        }
+        for s in &mut self.apply.statements {
+            s.mut_accept_mut(v);
+        }
+    }
+}
+
+impl PartialEq for Control {
+    fn eq(&self, other: &Control) -> bool {
+        self.name == other.name
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Parser {
+    pub name: String,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<ControlParameter>,
+    pub states: Vec<State>,
+    pub decl_only: bool,
+
+    /// The first token of this parser, used for error reporting.
+    pub token: Token,
+}
+
+impl Parser {
+    pub fn new(name: String, token: Token) -> Self {
+        Self {
+            name,
+            type_parameters: Vec::new(),
+            parameters: Vec::new(),
+            states: Vec::new(),
+            decl_only: false,
+            token,
+        }
+    }
+
+    pub fn is_type_parameter(&self, name: &str) -> bool {
+        for t in &self.type_parameters {
+            if t == name {
+                return true;
+            }
+        }
+        false
+    }
+
+    pub fn names(&self) -> HashMap<String, NameInfo> {
+        let mut names = HashMap::new();
+        for p in &self.parameters {
+            names.insert(
+                p.name.clone(),
+                NameInfo {
+                    ty: p.ty.clone(),
+                    decl: DeclarationInfo::Parameter(p.direction),
+                },
+            );
+        }
+        for s in &self.states {
+            names.insert(
+                s.name.clone(),
+                NameInfo {
+                    ty: Type::State,
+                    decl: DeclarationInfo::State,
+                },
+            );
+        }
+        names
+    }
+
+    pub fn get_start_state(&self) -> Option<&State> {
+        self.states.iter().find(|&s| s.name == "start")
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.parser(self);
+        for p in &self.parameters {
+            p.accept(v);
+        }
+        for s in &self.states {
+            s.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.parser(self);
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+        for s in &self.states {
+            s.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.parser(self);
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+        for s in &mut self.states {
+            s.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.parser(self);
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+        for s in &mut self.states {
+            s.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ControlParameter {
+    pub direction: Direction,
+    pub ty: Type,
+    pub name: String,
+
+    pub dir_token: Token,
+    pub ty_token: Token,
+    pub name_token: Token,
+}
+
+impl ControlParameter {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.control_parameter(self);
+        self.ty.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.control_parameter(self);
+        self.ty.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.control_parameter(self);
+        self.ty.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.control_parameter(self);
+        self.ty.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+pub enum Direction {
+    In,
+    Out,
+    InOut,
+    Unspecified,
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct StatementBlock {
+    pub statements: Vec<Statement>,
+}
+
+impl StatementBlock {
+    fn new() -> Self {
+        Self {
+            statements: Vec::new(),
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Action {
+    pub name: String,
+    pub parameters: Vec<ActionParameter>,
+    pub statement_block: StatementBlock,
+}
+
+impl Action {
+    pub fn new(name: String) -> Self {
+        Self {
+            name,
+            parameters: Vec::new(),
+            statement_block: StatementBlock::default(),
+        }
+    }
+
+    pub fn names(&self) -> HashMap<String, NameInfo> {
+        let mut names = HashMap::new();
+        for p in &self.parameters {
+            names.insert(
+                p.name.clone(),
+                NameInfo {
+                    ty: p.ty.clone(),
+                    decl: DeclarationInfo::ActionParameter(p.direction),
+                },
+            );
+        }
+        names
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.action(self);
+        for p in &self.parameters {
+            p.accept(v);
+        }
+        for s in &self.statement_block.statements {
+            s.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.action(self);
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+        for s in &self.statement_block.statements {
+            s.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.action(self);
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+        for s in &mut self.statement_block.statements {
+            s.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.action(self);
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+        for s in &mut self.statement_block.statements {
+            s.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ActionParameter {
+    pub direction: Direction,
+    pub ty: Type,
+    pub name: String,
+
+    pub ty_token: Token,
+    pub name_token: Token,
+}
+
+impl ActionParameter {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.action_parameter(self);
+        self.ty.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.action_parameter(self);
+        self.ty.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.action_parameter(self);
+        self.ty.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.action_parameter(self);
+        self.ty.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Table {
+    pub name: String,
+    pub actions: Vec<Lvalue>,
+    pub default_action: String,
+    pub key: Vec<(Lvalue, MatchKind)>,
+    pub const_entries: Vec<ConstTableEntry>,
+    pub size: usize,
+    pub token: Token,
+}
+
+impl Table {
+    pub fn new(name: String, token: Token) -> Self {
+        Self {
+            name,
+            actions: Vec::new(),
+            default_action: String::new(),
+            key: Vec::new(),
+            const_entries: Vec::new(),
+            size: 0,
+            token,
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.table(self);
+        for a in &self.actions {
+            a.accept(v);
+        }
+        for (lval, mk) in &self.key {
+            lval.accept(v);
+            mk.accept(v);
+        }
+        for e in &self.const_entries {
+            e.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.table(self);
+        for a in &self.actions {
+            a.accept_mut(v);
+        }
+        for (lval, mk) in &self.key {
+            lval.accept_mut(v);
+            mk.accept_mut(v);
+        }
+        for e in &self.const_entries {
+            e.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.table(self);
+        for a in &mut self.actions {
+            a.mut_accept(v);
+        }
+        for (lval, mk) in &mut self.key {
+            lval.mut_accept(v);
+            mk.mut_accept(v);
+        }
+        for e in &mut self.const_entries {
+            e.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.table(self);
+        for a in &mut self.actions {
+            a.mut_accept_mut(v);
+        }
+        for (lval, mk) in &mut self.key {
+            lval.mut_accept_mut(v);
+            mk.mut_accept_mut(v);
+        }
+        for e in &mut self.const_entries {
+            e.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ConstTableEntry {
+    pub keyset: Vec<KeySetElement>,
+    pub action: ActionRef,
+}
+
+impl ConstTableEntry {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.const_table_entry(self);
+        for k in &self.keyset {
+            k.accept(v);
+        }
+        self.action.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.const_table_entry(self);
+        for k in &self.keyset {
+            k.accept_mut(v);
+        }
+        self.action.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.const_table_entry(self);
+        for k in &mut self.keyset {
+            k.mut_accept(v);
+        }
+        self.action.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.const_table_entry(self);
+        for k in &mut self.keyset {
+            k.mut_accept_mut(v);
+        }
+        self.action.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct KeySetElement {
+    pub value: KeySetElementValue,
+    pub token: Token,
+}
+
+impl KeySetElement {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.key_set_element(self);
+        self.value.accept(v);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.key_set_element(self);
+        self.value.accept_mut(v);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.key_set_element(self);
+        self.value.mut_accept(v);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.key_set_element(self);
+        self.value.mut_accept_mut(v);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum KeySetElementValue {
+    Expression(Box<Expression>),
+    Default,
+    DontCare,
+    Masked(Box<Expression>, Box<Expression>),
+    Ranged(Box<Expression>, Box<Expression>),
+}
+
+impl KeySetElementValue {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.key_set_element_value(self);
+        match self {
+            KeySetElementValue::Expression(xpr) => xpr.accept(v),
+            KeySetElementValue::Default => {}
+            KeySetElementValue::DontCare => {}
+            KeySetElementValue::Masked(val, mask) => {
+                val.accept(v);
+                mask.accept(v);
+            }
+            KeySetElementValue::Ranged(begin, end) => {
+                begin.accept(v);
+                end.accept(v);
+            }
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.key_set_element_value(self);
+        match self {
+            KeySetElementValue::Expression(xpr) => xpr.accept_mut(v),
+            KeySetElementValue::Default => {}
+            KeySetElementValue::DontCare => {}
+            KeySetElementValue::Masked(val, mask) => {
+                val.accept_mut(v);
+                mask.accept_mut(v);
+            }
+            KeySetElementValue::Ranged(begin, end) => {
+                begin.accept_mut(v);
+                end.accept_mut(v);
+            }
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.key_set_element_value(self);
+        match self {
+            KeySetElementValue::Expression(xpr) => xpr.mut_accept(v),
+            KeySetElementValue::Default => {}
+            KeySetElementValue::DontCare => {}
+            KeySetElementValue::Masked(val, mask) => {
+                val.mut_accept(v);
+                mask.mut_accept(v);
+            }
+            KeySetElementValue::Ranged(begin, end) => {
+                begin.mut_accept(v);
+                end.mut_accept(v);
+            }
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.key_set_element_value(self);
+        match self {
+            KeySetElementValue::Expression(xpr) => xpr.mut_accept_mut(v),
+            KeySetElementValue::Default => {}
+            KeySetElementValue::DontCare => {}
+            KeySetElementValue::Masked(val, mask) => {
+                val.mut_accept_mut(v);
+                mask.mut_accept_mut(v);
+            }
+            KeySetElementValue::Ranged(begin, end) => {
+                begin.mut_accept_mut(v);
+                end.mut_accept_mut(v);
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ActionRef {
+    pub name: String,
+    pub parameters: Vec<Box<Expression>>,
+
+    pub token: Token,
+}
+
+impl ActionRef {
+    pub fn new(name: String, token: Token) -> Self {
+        Self {
+            name,
+            token,
+            parameters: Vec::new(),
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.action_ref(self);
+        for p in &self.parameters {
+            p.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.action_ref(self);
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.action_ref(self);
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.action_ref(self);
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum MatchKind {
+    Exact,
+    Ternary,
+    LongestPrefixMatch,
+    Range,
+}
+
+impl MatchKind {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.match_kind(self);
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.match_kind(self);
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.match_kind(self);
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.match_kind(self);
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum Statement {
+    Empty,
+    Assignment(Lvalue, Box<Expression>),
+    //TODO get rid of this in favor of ExpressionKind::Call ???
+    Call(Call),
+    If(IfBlock),
+    Variable(Variable),
+    Constant(Constant),
+    Transition(Transition),
+    Return(Option<Box<Expression>>),
+    // TODO ...
+}
+
+impl Statement {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.statement(self);
+        match self {
+            Statement::Empty => {}
+            Statement::Assignment(lval, xpr) => {
+                lval.accept(v);
+                xpr.accept(v);
+            }
+            Statement::Call(call) => call.accept(v),
+            Statement::If(if_block) => if_block.accept(v),
+            Statement::Variable(var) => var.accept(v),
+            Statement::Constant(constant) => constant.accept(v),
+            Statement::Transition(transition) => transition.accept(v),
+            Statement::Return(xpr) => {
+                if let Some(rx) = xpr {
+                    rx.accept(v);
+                }
+            }
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.statement(self);
+        match self {
+            Statement::Empty => {}
+            Statement::Assignment(lval, xpr) => {
+                lval.accept_mut(v);
+                xpr.accept_mut(v);
+            }
+            Statement::Call(call) => call.accept_mut(v),
+            Statement::If(if_block) => if_block.accept_mut(v),
+            Statement::Variable(var) => var.accept_mut(v),
+            Statement::Constant(constant) => constant.accept_mut(v),
+            Statement::Transition(transition) => transition.accept_mut(v),
+            Statement::Return(xpr) => {
+                if let Some(rx) = xpr {
+                    rx.accept_mut(v);
+                }
+            }
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.statement(self);
+        match self {
+            Statement::Empty => {}
+            Statement::Assignment(lval, xpr) => {
+                lval.mut_accept(v);
+                xpr.mut_accept(v);
+            }
+            Statement::Call(call) => call.mut_accept(v),
+            Statement::If(if_block) => if_block.mut_accept(v),
+            Statement::Variable(var) => var.mut_accept(v),
+            Statement::Constant(constant) => constant.mut_accept(v),
+            Statement::Transition(transition) => transition.mut_accept(v),
+            Statement::Return(xpr) => {
+                if let Some(rx) = xpr {
+                    rx.mut_accept(v);
+                }
+            }
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.statement(self);
+        match self {
+            Statement::Empty => {}
+            Statement::Assignment(lval, xpr) => {
+                lval.mut_accept_mut(v);
+                xpr.mut_accept_mut(v);
+            }
+            Statement::Call(call) => call.mut_accept_mut(v),
+            Statement::If(if_block) => if_block.mut_accept_mut(v),
+            Statement::Variable(var) => var.mut_accept_mut(v),
+            Statement::Constant(constant) => constant.mut_accept_mut(v),
+            Statement::Transition(transition) => transition.mut_accept_mut(v),
+            Statement::Return(xpr) => {
+                if let Some(rx) = xpr {
+                    rx.mut_accept_mut(v);
+                }
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct IfBlock {
+    pub predicate: Box<Expression>,
+    pub block: StatementBlock,
+    pub else_ifs: Vec<ElseIfBlock>,
+    pub else_block: Option<StatementBlock>,
+}
+
+impl IfBlock {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.if_block(self);
+        self.predicate.accept(v);
+        for s in &self.block.statements {
+            s.accept(v);
+        }
+        for ei in &self.else_ifs {
+            ei.accept(v);
+        }
+        if let Some(eb) = &self.else_block {
+            for s in &eb.statements {
+                s.accept(v);
+            }
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.if_block(self);
+        self.predicate.accept_mut(v);
+        for s in &self.block.statements {
+            s.accept_mut(v);
+        }
+        for ei in &self.else_ifs {
+            ei.accept_mut(v);
+        }
+        if let Some(eb) = &self.else_block {
+            for s in &eb.statements {
+                s.accept_mut(v);
+            }
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.if_block(self);
+        self.predicate.mut_accept(v);
+        for s in &mut self.block.statements {
+            s.mut_accept(v);
+        }
+        for ei in &mut self.else_ifs {
+            ei.mut_accept(v);
+        }
+        if let Some(eb) = &mut self.else_block {
+            for s in &mut eb.statements {
+                s.mut_accept(v);
+            }
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.if_block(self);
+        self.predicate.mut_accept_mut(v);
+        for s in &mut self.block.statements {
+            s.mut_accept_mut(v);
+        }
+        for ei in &mut self.else_ifs {
+            ei.mut_accept_mut(v);
+        }
+        if let Some(eb) = &mut self.else_block {
+            for s in &mut eb.statements {
+                s.mut_accept_mut(v);
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ElseIfBlock {
+    pub predicate: Box<Expression>,
+    pub block: StatementBlock,
+}
+
+impl ElseIfBlock {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.else_if_block(self);
+        self.predicate.accept(v);
+        for s in &self.block.statements {
+            s.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.else_if_block(self);
+        self.predicate.accept_mut(v);
+        for s in &self.block.statements {
+            s.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.else_if_block(self);
+        self.predicate.mut_accept(v);
+        for s in &mut self.block.statements {
+            s.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.else_if_block(self);
+        self.predicate.mut_accept_mut(v);
+        for s in &mut self.block.statements {
+            s.mut_accept_mut(v);
+        }
+    }
+}
+
+/// A function or method call
+#[derive(Debug, Clone)]
+pub struct Call {
+    pub lval: Lvalue,
+    pub args: Vec<Box<Expression>>,
+}
+
+impl Call {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.call(self);
+        self.lval.accept(v);
+        for a in &self.args {
+            a.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.call(self);
+        self.lval.accept_mut(v);
+        for a in &self.args {
+            a.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.call(self);
+        self.lval.mut_accept(v);
+        for a in &mut self.args {
+            a.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.call(self);
+        self.lval.mut_accept_mut(v);
+        for a in &mut self.args {
+            a.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Lvalue {
+    pub name: String,
+    pub token: Token,
+}
+
+impl Lvalue {
+    pub fn parts(&self) -> Vec<&str> {
+        self.name.split('.').collect()
+    }
+    pub fn root(&self) -> &str {
+        self.parts()[0]
+    }
+    pub fn leaf(&self) -> &str {
+        let parts = self.parts();
+        parts[parts.len() - 1]
+    }
+    pub fn degree(&self) -> usize {
+        self.parts().len()
+    }
+    pub fn pop_left(&self) -> Self {
+        let parts = self.parts();
+        Lvalue {
+            name: parts[1..].join("."),
+            token: Token {
+                kind: self.token.kind.clone(),
+                line: self.token.line,
+                col: self.token.col + parts[0].len() + 1,
+                file: self.token.file.clone(),
+            },
+        }
+    }
+    pub fn pop_right(&self) -> Self {
+        let parts = self.parts();
+        Lvalue {
+            name: parts[..parts.len() - 1].join("."),
+            token: Token {
+                kind: self.token.kind.clone(),
+                line: self.token.line,
+                col: self.token.col,
+                file: self.token.file.clone(),
+            },
+        }
+    }
+    fn accept<V: Visitor>(&self, v: &V) {
+        v.lvalue(self);
+    }
+
+    fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.lvalue(self);
+    }
+
+    fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.lvalue(self);
+    }
+
+    fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.lvalue(self);
+    }
+}
+
+impl std::hash::Hash for Lvalue {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.name.hash(state);
+    }
+}
+
+impl PartialEq for Lvalue {
+    fn eq(&self, other: &Self) -> bool {
+        self.name == other.name
+    }
+}
+impl Eq for Lvalue {}
+
+impl PartialOrd for Lvalue {
+    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
+impl Ord for Lvalue {
+    fn cmp(&self, other: &Self) -> std::cmp::Ordering {
+        self.name.cmp(&other.name)
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct State {
+    pub name: String,
+    pub statements: StatementBlock,
+    pub token: Token,
+}
+
+impl State {
+    pub fn new(name: String, token: Token) -> Self {
+        Self {
+            name,
+            statements: StatementBlock::new(),
+            token,
+        }
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.state(self);
+        for s in &self.statements.statements {
+            s.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.state(self);
+        for s in &self.statements.statements {
+            s.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.state(self);
+        for s in &mut self.statements.statements {
+            s.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.state(self);
+        for s in &mut self.statements.statements {
+            s.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub enum Transition {
+    Reference(Lvalue),
+    Select(Select),
+}
+
+impl Transition {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.transition(self);
+        match self {
+            Transition::Reference(lval) => lval.accept(v),
+            Transition::Select(sel) => sel.accept(v),
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.transition(self);
+        match self {
+            Transition::Reference(lval) => lval.accept_mut(v),
+            Transition::Select(sel) => sel.accept_mut(v),
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.transition(self);
+        match self {
+            Transition::Reference(lval) => lval.mut_accept(v),
+            Transition::Select(sel) => sel.mut_accept(v),
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.transition(self);
+        match self {
+            Transition::Reference(lval) => lval.mut_accept_mut(v),
+            Transition::Select(sel) => sel.mut_accept_mut(v),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Default)]
+pub struct Select {
+    pub parameters: Vec<Box<Expression>>,
+    pub elements: Vec<SelectElement>,
+}
+
+impl Select {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.select(self);
+        for p in &self.parameters {
+            p.accept(v);
+        }
+        for e in &self.elements {
+            e.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.select(self);
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+        for e in &self.elements {
+            e.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.select(self);
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+        for e in &mut self.elements {
+            e.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.select(self);
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+        for e in &mut self.elements {
+            e.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct SelectElement {
+    pub keyset: Vec<KeySetElement>,
+    pub name: String,
+}
+
+impl SelectElement {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.select_element(self);
+        for k in &self.keyset {
+            k.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.select_element(self);
+        for k in &self.keyset {
+            k.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.select_element(self);
+        for k in &mut self.keyset {
+            k.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.select_element(self);
+        for k in &mut self.keyset {
+            k.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct Extern {
+    pub name: String,
+    pub methods: Vec<ExternMethod>,
+    pub token: Token,
+}
+
+impl Extern {
+    pub fn names(&self) -> HashMap<String, NameInfo> {
+        let mut names = HashMap::new();
+        for p in &self.methods {
+            names.insert(
+                p.name.clone(),
+                NameInfo {
+                    ty: Type::ExternFunction,
+                    decl: DeclarationInfo::Method,
+                },
+            );
+        }
+        names
+    }
+
+    pub fn get_method(&self, name: &str) -> Option<&ExternMethod> {
+        self.methods.iter().find(|&m| m.name == name)
+    }
+
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.p4extern(self);
+        for m in &self.methods {
+            m.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.p4extern(self);
+        for m in &self.methods {
+            m.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.p4extern(self);
+        for m in &mut self.methods {
+            m.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.p4extern(self);
+        for m in &mut self.methods {
+            m.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone)]
+pub struct ExternMethod {
+    pub return_type: Type,
+    pub name: String,
+    pub type_parameters: Vec<String>,
+    pub parameters: Vec<ControlParameter>,
+}
+
+impl ExternMethod {
+    pub fn accept<V: Visitor>(&self, v: &V) {
+        v.extern_method(self);
+        self.return_type.accept(v);
+        for p in &self.parameters {
+            p.accept(v);
+        }
+    }
+
+    pub fn accept_mut<V: VisitorMut>(&self, v: &mut V) {
+        v.extern_method(self);
+        self.return_type.accept_mut(v);
+        for p in &self.parameters {
+            p.accept_mut(v);
+        }
+    }
+
+    pub fn mut_accept<V: MutVisitor>(&mut self, v: &V) {
+        v.extern_method(self);
+        self.return_type.mut_accept(v);
+        for p in &mut self.parameters {
+            p.mut_accept(v);
+        }
+    }
+
+    pub fn mut_accept_mut<V: MutVisitorMut>(&mut self, v: &mut V) {
+        v.extern_method(self);
+        self.return_type.mut_accept_mut(v);
+        for p in &mut self.parameters {
+            p.mut_accept_mut(v);
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq)]
+pub enum DeclarationInfo {
+    Parameter(Direction),
+    Method,
+    StructMember,
+    HeaderMember,
+    Local,
+    ControlTable,
+    ControlMember,
+    State,
+    Action,
+    ActionParameter(Direction),
+}
+
+#[derive(Debug, Clone)]
+pub struct NameInfo {
+    pub ty: Type,
+    pub decl: DeclarationInfo,
+}
+
+pub trait Visitor {
+    fn constant(&self, _: &Constant) {}
+    fn header(&self, _: &Header) {}
+    fn p4struct(&self, _: &Struct) {}
+    fn typedef(&self, _: &Typedef) {}
+    fn control(&self, _: &Control) {}
+    fn parser(&self, _: &Parser) {}
+    fn package(&self, _: &Package) {}
+    fn package_instance(&self, _: &PackageInstance) {}
+    fn p4extern(&self, _: &Extern) {}
+
+    fn statement(&self, _: &Statement) {}
+    fn action(&self, _: &Action) {}
+    fn control_parameter(&self, _: &ControlParameter) {}
+    fn action_parameter(&self, _: &ActionParameter) {}
+    fn expression(&self, _: &Expression) {}
+    fn header_member(&self, _: &HeaderMember) {}
+    fn struct_member(&self, _: &StructMember) {}
+    fn call(&self, _: &Call) {}
+    fn typ(&self, _: &Type) {}
+    fn binop(&self, _: &BinOp) {}
+    fn lvalue(&self, _: &Lvalue) {}
+    fn variable(&self, _: &Variable) {}
+    fn if_block(&self, _: &IfBlock) {}
+    fn else_if_block(&self, _: &ElseIfBlock) {}
+    fn transition(&self, _: &Transition) {}
+    fn select(&self, _: &Select) {}
+    fn select_element(&self, _: &SelectElement) {}
+    fn key_set_element(&self, _: &KeySetElement) {}
+    fn key_set_element_value(&self, _: &KeySetElementValue) {}
+    fn table(&self, _: &Table) {}
+    fn match_kind(&self, _: &MatchKind) {}
+    fn const_table_entry(&self, _: &ConstTableEntry) {}
+    fn action_ref(&self, _: &ActionRef) {}
+    fn state(&self, _: &State) {}
+    fn package_parameter(&self, _: &PackageParameter) {}
+    fn extern_method(&self, _: &ExternMethod) {}
+}
+
+pub trait VisitorMut {
+    fn constant(&mut self, _: &Constant) {}
+    fn header(&mut self, _: &Header) {}
+    fn p4struct(&mut self, _: &Struct) {}
+    fn typedef(&mut self, _: &Typedef) {}
+    fn control(&mut self, _: &Control) {}
+    fn parser(&mut self, _: &Parser) {}
+    fn package(&mut self, _: &Package) {}
+    fn package_instance(&mut self, _: &PackageInstance) {}
+    fn p4extern(&mut self, _: &Extern) {}
+
+    fn statement(&mut self, _: &Statement) {}
+    fn action(&mut self, _: &Action) {}
+    fn control_parameter(&mut self, _: &ControlParameter) {}
+    fn action_parameter(&mut self, _: &ActionParameter) {}
+    fn expression(&mut self, _: &Expression) {}
+    fn header_member(&mut self, _: &HeaderMember) {}
+    fn struct_member(&mut self, _: &StructMember) {}
+    fn call(&mut self, _: &Call) {}
+    fn typ(&mut self, _: &Type) {}
+    fn binop(&mut self, _: &BinOp) {}
+    fn lvalue(&mut self, _: &Lvalue) {}
+    fn variable(&mut self, _: &Variable) {}
+    fn if_block(&mut self, _: &IfBlock) {}
+    fn else_if_block(&mut self, _: &ElseIfBlock) {}
+    fn transition(&mut self, _: &Transition) {}
+    fn select(&mut self, _: &Select) {}
+    fn select_element(&mut self, _: &SelectElement) {}
+    fn key_set_element(&mut self, _: &KeySetElement) {}
+    fn key_set_element_value(&mut self, _: &KeySetElementValue) {}
+    fn table(&mut self, _: &Table) {}
+    fn match_kind(&mut self, _: &MatchKind) {}
+    fn const_table_entry(&mut self, _: &ConstTableEntry) {}
+    fn action_ref(&mut self, _: &ActionRef) {}
+    fn state(&mut self, _: &State) {}
+    fn package_parameter(&mut self, _: &PackageParameter) {}
+    fn extern_method(&mut self, _: &ExternMethod) {}
+}
+
+pub trait MutVisitor {
+    fn constant(&self, _: &mut Constant) {}
+    fn header(&self, _: &mut Header) {}
+    fn p4struct(&self, _: &mut Struct) {}
+    fn typedef(&self, _: &mut Typedef) {}
+    fn control(&self, _: &mut Control) {}
+    fn parser(&self, _: &mut Parser) {}
+    fn package(&self, _: &mut Package) {}
+    fn package_instance(&self, _: &mut PackageInstance) {}
+    fn p4extern(&self, _: &mut Extern) {}
+
+    fn statement(&self, _: &mut Statement) {}
+    fn action(&self, _: &mut Action) {}
+    fn control_parameter(&self, _: &mut ControlParameter) {}
+    fn action_parameter(&self, _: &mut ActionParameter) {}
+    fn expression(&self, _: &mut Expression) {}
+    fn header_member(&self, _: &mut HeaderMember) {}
+    fn struct_member(&self, _: &mut StructMember) {}
+    fn call(&self, _: &mut Call) {}
+    fn typ(&self, _: &mut Type) {}
+    fn binop(&self, _: &mut BinOp) {}
+    fn lvalue(&self, _: &mut Lvalue) {}
+    fn variable(&self, _: &mut Variable) {}
+    fn if_block(&self, _: &mut IfBlock) {}
+    fn else_if_block(&self, _: &mut ElseIfBlock) {}
+    fn transition(&self, _: &mut Transition) {}
+    fn select(&self, _: &mut Select) {}
+    fn select_element(&self, _: &mut SelectElement) {}
+    fn key_set_element(&self, _: &mut KeySetElement) {}
+    fn key_set_element_value(&self, _: &mut KeySetElementValue) {}
+    fn table(&self, _: &mut Table) {}
+    fn match_kind(&self, _: &mut MatchKind) {}
+    fn const_table_entry(&self, _: &mut ConstTableEntry) {}
+    fn action_ref(&self, _: &mut ActionRef) {}
+    fn state(&self, _: &mut State) {}
+    fn package_parameter(&self, _: &mut PackageParameter) {}
+    fn extern_method(&self, _: &mut ExternMethod) {}
+}
+
+pub trait MutVisitorMut {
+    fn constant(&mut self, _: &mut Constant) {}
+    fn header(&mut self, _: &mut Header) {}
+    fn p4struct(&mut self, _: &mut Struct) {}
+    fn typedef(&mut self, _: &mut Typedef) {}
+    fn control(&mut self, _: &mut Control) {}
+    fn parser(&mut self, _: &mut Parser) {}
+    fn package(&mut self, _: &mut Package) {}
+    fn package_instance(&mut self, _: &mut PackageInstance) {}
+    fn p4extern(&mut self, _: &mut Extern) {}
+
+    fn statement(&mut self, _: &mut Statement) {}
+    fn action(&mut self, _: &mut Action) {}
+    fn control_parameter(&mut self, _: &mut ControlParameter) {}
+    fn action_parameter(&mut self, _: &mut ActionParameter) {}
+    fn expression(&mut self, _: &mut Expression) {}
+    fn header_member(&mut self, _: &mut HeaderMember) {}
+    fn struct_member(&mut self, _: &mut StructMember) {}
+    fn call(&mut self, _: &mut Call) {}
+    fn typ(&mut self, _: &mut Type) {}
+    fn binop(&mut self, _: &mut BinOp) {}
+    fn lvalue(&mut self, _: &mut Lvalue) {}
+    fn variable(&mut self, _: &mut Variable) {}
+    fn if_block(&mut self, _: &mut IfBlock) {}
+    fn else_if_block(&mut self, _: &mut ElseIfBlock) {}
+    fn transition(&mut self, _: &mut Transition) {}
+    fn select(&mut self, _: &mut Select) {}
+    fn select_element(&mut self, _: &mut SelectElement) {}
+    fn key_set_element(&mut self, _: &mut KeySetElement) {}
+    fn key_set_element_value(&mut self, _: &mut KeySetElementValue) {}
+    fn table(&mut self, _: &mut Table) {}
+    fn match_kind(&mut self, _: &mut MatchKind) {}
+    fn const_table_entry(&mut self, _: &mut ConstTableEntry) {}
+    fn action_ref(&mut self, _: &mut ActionRef) {}
+    fn state(&mut self, _: &mut State) {}
+    fn package_parameter(&mut self, _: &mut PackageParameter) {}
+    fn extern_method(&mut self, _: &mut ExternMethod) {}
+}
+
\ No newline at end of file diff --git a/src/p4/check.rs.html b/src/p4/check.rs.html new file mode 100644 index 00000000..57a93b01 --- /dev/null +++ b/src/p4/check.rs.html @@ -0,0 +1,2075 @@ +check.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+
// Copyright 2022 Oxide Computer Company
+
+use std::collections::HashMap;
+
+use crate::ast::{
+    Call, Control, DeclarationInfo, Expression, ExpressionKind, Header, Lvalue,
+    NameInfo, Parser, State, Statement, StatementBlock, Struct, Table,
+    Transition, Type, VisitorMut, AST,
+};
+use crate::hlir::{Hlir, HlirGenerator};
+use crate::lexer::Token;
+use colored::Colorize;
+
+// TODO Check List
+// This is a running list of things to check
+//
+// - Table keys should be constrained to bit, varbit, int
+
+#[derive(Debug, Clone)]
+pub struct Diagnostic {
+    /// Level of this diagnostic.
+    pub level: Level,
+
+    /// Message associated with this diagnostic.
+    pub message: String,
+
+    /// The first token from the lexical element where the semantic error was
+    /// detected.
+    pub token: Token,
+}
+
+#[derive(Debug, PartialEq, Clone, Eq)]
+pub enum Level {
+    Info,
+    Deprecation,
+    Warning,
+    Error,
+}
+
+#[derive(Debug, Default)]
+pub struct Diagnostics(pub Vec<Diagnostic>);
+
+impl Diagnostics {
+    pub fn new() -> Self {
+        Diagnostics(Vec::new())
+    }
+    pub fn errors(&self) -> Vec<&Diagnostic> {
+        self.0.iter().filter(|x| x.level == Level::Error).collect()
+    }
+    pub fn extend(&mut self, diags: &Diagnostics) {
+        self.0.extend(diags.0.clone())
+    }
+    pub fn push(&mut self, d: Diagnostic) {
+        self.0.push(d);
+    }
+}
+
+pub fn all(ast: &AST) -> (Hlir, Diagnostics) {
+    let mut diags = Diagnostics::new();
+    let mut hg = HlirGenerator::new(ast);
+    hg.run();
+    diags.extend(&hg.diags);
+
+    if !diags.errors().is_empty() {
+        return (hg.hlir, diags);
+    }
+
+    for p in &ast.parsers {
+        diags.extend(&ParserChecker::check(p, ast));
+    }
+    for c in &ast.controls {
+        diags.extend(&ControlChecker::check(c, ast, &hg.hlir));
+    }
+    for s in &ast.structs {
+        diags.extend(&StructChecker::check(s, ast));
+    }
+    for h in &ast.headers {
+        diags.extend(&HeaderChecker::check(h, ast));
+    }
+    (hg.hlir, diags)
+}
+
+pub struct ControlChecker {}
+
+impl ControlChecker {
+    pub fn check(c: &Control, ast: &AST, hlir: &Hlir) -> Diagnostics {
+        let mut diags = Diagnostics::new();
+        let names = c.names();
+        Self::check_params(c, ast, &mut diags);
+        Self::check_tables(c, &names, ast, &mut diags);
+        Self::check_variables(c, ast, &mut diags);
+        Self::check_actions(c, ast, hlir, &mut diags);
+        Self::check_apply(c, ast, hlir, &mut diags);
+        diags
+    }
+
+    pub fn check_params(c: &Control, ast: &AST, diags: &mut Diagnostics) {
+        for p in &c.parameters {
+            if let Type::UserDefined(typename) = &p.ty {
+                if ast.get_user_defined_type(typename).is_none() {
+                    diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: format!("Typename {} not found", typename),
+                        token: p.ty_token.clone(),
+                    })
+                }
+            }
+        }
+    }
+
+    pub fn check_tables(
+        c: &Control,
+        names: &HashMap<String, NameInfo>,
+        ast: &AST,
+        diags: &mut Diagnostics,
+    ) {
+        for t in &c.tables {
+            Self::check_table(c, t, names, ast, diags);
+        }
+    }
+
+    pub fn check_table(
+        c: &Control,
+        t: &Table,
+        names: &HashMap<String, NameInfo>,
+        ast: &AST,
+        diags: &mut Diagnostics,
+    ) {
+        for (lval, _match_kind) in &t.key {
+            diags.extend(&check_lvalue(lval, ast, names, Some(&c.name)))
+        }
+        if t.default_action.is_empty() {
+            diags.push(Diagnostic {
+                level: Level::Error,
+                message: "Table must have a default action".into(),
+                token: t.token.clone(),
+            });
+        }
+    }
+
+    pub fn check_variables(c: &Control, ast: &AST, diags: &mut Diagnostics) {
+        for v in &c.variables {
+            if let Type::UserDefined(typename) = &v.ty {
+                if ast.get_user_defined_type(typename).is_some() {
+                    continue;
+                }
+                if ast.get_control(typename).is_some() {
+                    continue;
+                }
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!("Typename {} not found", typename),
+                    token: v.token.clone(),
+                })
+            }
+        }
+    }
+
+    pub fn check_actions(
+        c: &Control,
+        ast: &AST,
+        hlir: &Hlir,
+        diags: &mut Diagnostics,
+    ) {
+        for t in &c.tables {
+            Self::check_table_action_reference(c, t, ast, diags);
+        }
+        for a in &c.actions {
+            check_statement_block(&a.statement_block, hlir, diags);
+        }
+    }
+
+    pub fn check_table_action_reference(
+        c: &Control,
+        t: &Table,
+        _ast: &AST,
+        diags: &mut Diagnostics,
+    ) {
+        for a in &t.actions {
+            if c.get_action(&a.name).is_none() {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "Table {} does not have action {}",
+                        t.name, &a.name,
+                    ),
+                    token: a.token.clone(), //TODO plumb token for lvalue
+                });
+            }
+        }
+    }
+
+    pub fn check_apply(
+        c: &Control,
+        ast: &AST,
+        hlir: &Hlir,
+        diags: &mut Diagnostics,
+    ) {
+        diags.extend(&check_statement_block_lvalues(&c.apply, ast, &c.names()));
+
+        let mut apc = ApplyCallChecker {
+            c,
+            ast,
+            hlir,
+            diags,
+        };
+        c.accept_mut(&mut apc);
+    }
+}
+
+fn check_statement_block(
+    block: &StatementBlock,
+    hlir: &Hlir,
+    diags: &mut Diagnostics,
+) {
+    for s in &block.statements {
+        match s {
+            Statement::Assignment(lval, xpr) => {
+                let name_info = match hlir.lvalue_decls.get(lval) {
+                    Some(info) => info,
+                    None => {
+                        diags.push(Diagnostic {
+                            level: Level::Error,
+                            message: format!(
+                                "Could not resolve lvalue {}",
+                                &lval.name,
+                            ),
+                            token: lval.token.clone(),
+                        });
+                        return;
+                    }
+                };
+
+                let expression_type =
+                    match hlir.expression_types.get(xpr.as_ref()) {
+                        Some(ty) => ty,
+                        None => {
+                            diags.push(Diagnostic {
+                                level: Level::Error,
+                                message: "Could not determine expression type"
+                                    .to_owned(),
+                                token: xpr.token.clone(),
+                            });
+                            return;
+                        }
+                    };
+
+                if &name_info.ty != expression_type {
+                    diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: format!(
+                            "Cannot assign {} to {}",
+                            expression_type, &name_info.ty,
+                        ),
+                        token: xpr.token.clone(),
+                    });
+                }
+            }
+            Statement::Empty => {}
+            _ => {
+                // TODO
+            }
+        }
+    }
+}
+
+pub struct ApplyCallChecker<'a> {
+    c: &'a Control,
+    ast: &'a AST,
+    hlir: &'a Hlir,
+    diags: &'a mut Diagnostics,
+}
+
+impl<'a> VisitorMut for ApplyCallChecker<'a> {
+    fn call(&mut self, call: &Call) {
+        let name = call.lval.root();
+        let names = self.c.names();
+        let name_info = match names.get(name) {
+            Some(info) => info,
+            None => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!("{} is undefined", name),
+                    token: call.lval.token.clone(),
+                });
+                return;
+            }
+        };
+
+        match &name_info.ty {
+            Type::UserDefined(name) => {
+                if let Some(ctl) = self.ast.get_control(name) {
+                    self.check_apply_ctl_apply(call, ctl)
+                }
+            }
+            Type::Table => {
+                if let Some(tbl) = self.c.get_table(name) {
+                    self.check_apply_table_apply(call, tbl)
+                }
+            }
+            _ => {
+                //TODO
+            }
+        }
+    }
+}
+
+impl<'a> ApplyCallChecker<'a> {
+    pub fn check_apply_table_apply(&mut self, _call: &Call, _tbl: &Table) {
+        //TODO
+    }
+
+    pub fn check_apply_ctl_apply(&mut self, call: &Call, ctl: &Control) {
+        if call.args.len() != ctl.parameters.len() {
+            let signature: Vec<String> = ctl
+                .parameters
+                .iter()
+                .map(|x| x.ty.to_string().bright_blue().to_string())
+                .collect();
+
+            let signature = format!("{}({})", ctl.name, signature.join(", "));
+
+            self.diags.push(Diagnostic {
+                level: Level::Error,
+                message: format!(
+                    "{} arguments provided to control {}, {} required\n    \
+                    expected signature: {}",
+                    call.args.len().to_string().yellow(),
+                    ctl.name.blue(),
+                    ctl.parameters.len().to_string().yellow(),
+                    signature,
+                ),
+                token: call.lval.token.clone(),
+            });
+            return;
+        }
+
+        for (i, arg) in call.args.iter().enumerate() {
+            let arg_t = match self.hlir.expression_types.get(arg) {
+                Some(typ) => typ,
+                None => panic!("bug: no type for expression {:?}", arg),
+            };
+            let param = &ctl.parameters[i];
+            if arg_t != &param.ty {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "wrong argument type for {} parameter {}\n    \
+                         argument provided:  {}\n    \
+                         parameter requires: {}",
+                        ctl.name.bright_blue(),
+                        param.name.bright_blue(),
+                        format!("{}", arg_t).bright_blue(),
+                        format!("{}", param.ty).bright_blue(),
+                    ),
+                    token: arg.token.clone(),
+                });
+            }
+        }
+    }
+}
+
+pub struct ParserChecker {}
+
+impl ParserChecker {
+    pub fn check(p: &Parser, ast: &AST) -> Diagnostics {
+        let mut diags = Diagnostics::new();
+
+        if !p.decl_only {
+            Self::start_state(p, &mut diags);
+            for s in &p.states {
+                Self::ensure_transition(s, &mut diags);
+            }
+            Self::lvalues(p, ast, &mut diags);
+        }
+
+        diags
+    }
+
+    /// Ensure the parser has a start state
+    pub fn start_state(parser: &Parser, diags: &mut Diagnostics) {
+        for s in &parser.states {
+            if s.name == "start" {
+                return;
+            }
+        }
+
+        diags.push(Diagnostic {
+            level: Level::Error,
+            message: format!(
+                "start state not found for parser {}",
+                parser.name.bright_blue(),
+            ),
+            token: parser.token.clone(),
+        });
+    }
+
+    pub fn ensure_transition(state: &State, diags: &mut Diagnostics) {
+        let stmts = &state.statements.statements;
+
+        if stmts.is_empty() {
+            diags.push(Diagnostic {
+                level: Level::Error,
+                message: "state must include transition".into(),
+                token: state.token.clone(),
+            });
+        }
+
+        //TODO the right thing to do here is to ensure all code paths end in a
+        //     transition, for now just check that the last statement is a
+        //     transition.
+        let last = stmts.last();
+        if !matches!(last, Some(Statement::Transition(_))) {
+            diags.push(Diagnostic {
+                level: Level::Error,
+                message: "final parser state statement must be a transition"
+                    .into(),
+                token: state.token.clone(),
+            });
+        }
+    }
+
+    /// Check lvalue references
+    pub fn lvalues(parser: &Parser, ast: &AST, diags: &mut Diagnostics) {
+        for state in &parser.states {
+            // create a name context for each parser state to pick up any
+            // variables that may get created within parser states to reference
+            // locally.
+            let names = parser.names();
+            diags.extend(&check_statement_block_lvalues(
+                &state.statements,
+                ast,
+                &names,
+            ));
+        }
+    }
+}
+
+pub struct StructChecker {}
+
+impl StructChecker {
+    pub fn check(s: &Struct, ast: &AST) -> Diagnostics {
+        let mut diags = Diagnostics::new();
+        for m in &s.members {
+            if let Type::UserDefined(typename) = &m.ty {
+                if ast.get_user_defined_type(typename).is_none() {
+                    diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: format!(
+                            "Typename {} not found",
+                            typename.bright_blue()
+                        ),
+                        token: m.token.clone(),
+                    })
+                }
+            }
+        }
+        diags
+    }
+}
+
+pub struct HeaderChecker {}
+
+impl HeaderChecker {
+    pub fn check(h: &Header, ast: &AST) -> Diagnostics {
+        let mut diags = Diagnostics::new();
+        for m in &h.members {
+            if let Type::UserDefined(typename) = &m.ty {
+                if ast.get_user_defined_type(typename).is_none() {
+                    diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: format!(
+                            "Typename {} not found",
+                            typename.bright_blue()
+                        ),
+                        token: m.token.clone(),
+                    })
+                }
+            }
+        }
+        diags
+    }
+}
+
+fn check_name(
+    name: &str,
+    names: &HashMap<String, NameInfo>,
+    token: &Token,
+    parent: Option<&str>,
+) -> (Diagnostics, Option<Type>) {
+    match names.get(name) {
+        Some(name_info) => (Diagnostics::new(), Some(name_info.ty.clone())),
+        None => (
+            Diagnostics(vec![Diagnostic {
+                level: Level::Error,
+                message: match parent {
+                    Some(p) => format!(
+                        "{} does not have member {}",
+                        p.bright_blue(),
+                        name.bright_blue(),
+                    ),
+                    None => format!("'{}' is undefined", name),
+                },
+                token: token.clone(),
+            }]),
+            None,
+        ),
+    }
+}
+
+fn check_statement_lvalues(
+    stmt: &Statement,
+    ast: &AST,
+    names: &mut HashMap<String, NameInfo>,
+) -> Diagnostics {
+    let mut diags = Diagnostics::new();
+    match stmt {
+        Statement::Empty => {}
+        Statement::Variable(v) => {
+            match &v.initializer {
+                Some(expr) => {
+                    diags.extend(&check_expression_lvalues(
+                        expr.as_ref(),
+                        ast,
+                        names,
+                    ));
+                }
+                None => {}
+            };
+            names.insert(
+                v.name.clone(),
+                NameInfo {
+                    ty: v.ty.clone(),
+                    decl: DeclarationInfo::Local,
+                },
+            );
+        }
+        Statement::Constant(c) => {
+            diags.extend(&check_expression_lvalues(
+                c.initializer.as_ref(),
+                ast,
+                names,
+            ));
+        }
+        Statement::Assignment(lval, expr) => {
+            diags.extend(&check_lvalue(lval, ast, names, None));
+            diags.extend(&check_expression_lvalues(expr, ast, names));
+        }
+        Statement::Call(call) => {
+            diags.extend(&check_lvalue(&call.lval, ast, names, None));
+            for arg in &call.args {
+                diags.extend(&check_expression_lvalues(
+                    arg.as_ref(),
+                    ast,
+                    names,
+                ));
+            }
+        }
+        Statement::If(if_block) => {
+            diags.extend(&check_expression_lvalues(
+                if_block.predicate.as_ref(),
+                ast,
+                names,
+            ));
+            diags.extend(&check_statement_block_lvalues(
+                &if_block.block,
+                ast,
+                names,
+            ));
+            for elif in &if_block.else_ifs {
+                diags.extend(&check_expression_lvalues(
+                    elif.predicate.as_ref(),
+                    ast,
+                    names,
+                ));
+                diags.extend(&check_statement_block_lvalues(
+                    &elif.block,
+                    ast,
+                    names,
+                ));
+            }
+            if let Some(ref else_block) = if_block.else_block {
+                diags.extend(&check_statement_block_lvalues(
+                    else_block, ast, names,
+                ));
+            }
+        }
+        Statement::Transition(transition) => {
+            match transition {
+                Transition::Reference(lval) => {
+                    if lval.name != "accept" && lval.name != "reject" {
+                        diags.extend(&check_lvalue(lval, ast, names, None));
+                    }
+                }
+                Transition::Select(_sel) => {
+                    //TODO
+                }
+            }
+        }
+        Statement::Return(xpr) => {
+            if let Some(xpr) = xpr {
+                diags.extend(&check_expression_lvalues(
+                    xpr.as_ref(),
+                    ast,
+                    names,
+                ));
+            }
+        }
+    }
+    diags
+}
+
+fn check_statement_block_lvalues(
+    block: &StatementBlock,
+    ast: &AST,
+    names: &HashMap<String, NameInfo>,
+) -> Diagnostics {
+    let mut diags = Diagnostics::new();
+    let mut block_names = names.clone();
+    for stmt in &block.statements {
+        diags.extend(&check_statement_lvalues(stmt, ast, &mut block_names));
+    }
+    diags
+}
+
+fn check_expression_lvalues(
+    xpr: &Expression,
+    ast: &AST,
+    names: &HashMap<String, NameInfo>,
+) -> Diagnostics {
+    match &xpr.kind {
+        ExpressionKind::Lvalue(lval) => check_lvalue(lval, ast, names, None),
+        ExpressionKind::Binary(lhs, _, rhs) => {
+            let mut diags = Diagnostics::new();
+            diags.extend(&check_expression_lvalues(lhs.as_ref(), ast, names));
+            diags.extend(&check_expression_lvalues(rhs.as_ref(), ast, names));
+            diags
+        }
+        ExpressionKind::Index(lval, xpr) => {
+            let mut diags = Diagnostics::new();
+            diags.extend(&check_lvalue(lval, ast, names, None));
+            diags.extend(&check_expression_lvalues(xpr.as_ref(), ast, names));
+            diags
+        }
+        ExpressionKind::Slice(lhs, rhs) => {
+            let mut diags = Diagnostics::new();
+            diags.extend(&check_expression_lvalues(lhs.as_ref(), ast, names));
+            diags.extend(&check_expression_lvalues(rhs.as_ref(), ast, names));
+            diags
+        }
+        _ => Diagnostics::new(),
+    }
+}
+
+fn check_lvalue(
+    lval: &Lvalue,
+    ast: &AST,
+    names: &HashMap<String, NameInfo>,
+    parent: Option<&str>,
+) -> Diagnostics {
+    let parts = lval.parts();
+
+    let ty = match check_name(parts[0], names, &lval.token, parent) {
+        (_, Some(ty)) => ty,
+        (diags, None) => return diags,
+    };
+
+    let mut diags = Diagnostics::new();
+
+    match ty {
+        Type::Bool => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "bool".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::State => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "state".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Action => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "action".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Error => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "error".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Bit(size) => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        format!("bit<{}>", size).bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Varbit(size) => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        format!("varbit<{}>", size).bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Int(size) => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type int<{}> does not have a member {}",
+                        format!("int<{}>", size).bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::String => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "string".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::ExternFunction => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "extern functions do not have members".into(),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::HeaderMethod => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "header methods do not have members".into(),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Table => {
+            if parts.len() > 1 && parts.last() != Some(&"apply") {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "table".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::Void => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "void".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::List(_) => {
+            if parts.len() > 1 {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} does not have a member {}",
+                        "list".bright_blue(),
+                        parts[1].bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+        Type::UserDefined(name) => {
+            // get the parent type definition from the AST and check for the
+            // referenced member
+            if let Some(parent) = ast.get_struct(&name) {
+                if parts.len() > 1 {
+                    let mut struct_names = names.clone();
+                    struct_names.extend(parent.names());
+                    let mut token = lval.token.clone();
+                    token.col += parts[0].len() + 1;
+                    let sub_lval = Lvalue {
+                        name: parts[1..].join("."),
+                        token,
+                    };
+                    let sub_diags = check_lvalue(
+                        &sub_lval,
+                        ast,
+                        &struct_names,
+                        Some(&parent.name),
+                    );
+                    diags.extend(&sub_diags);
+                }
+            } else if let Some(parent) = ast.get_header(&name) {
+                if parts.len() > 1 {
+                    let mut header_names = names.clone();
+                    header_names.extend(parent.names());
+                    let mut token = lval.token.clone();
+                    token.col += parts[0].len() + 1;
+                    let sub_lval = Lvalue {
+                        name: parts[1..].join("."),
+                        token,
+                    };
+                    let sub_diags = check_lvalue(
+                        &sub_lval,
+                        ast,
+                        &header_names,
+                        Some(&parent.name),
+                    );
+                    diags.extend(&sub_diags);
+                }
+            } else if let Some(parent) = ast.get_extern(&name) {
+                if parts.len() > 1 {
+                    let mut extern_names = names.clone();
+                    extern_names.extend(parent.names());
+                    let mut token = lval.token.clone();
+                    token.col += parts[0].len() + 1;
+                    let sub_lval = Lvalue {
+                        name: parts[1..].join("."),
+                        token,
+                    };
+                    let sub_diags = check_lvalue(
+                        &sub_lval,
+                        ast,
+                        &extern_names,
+                        Some(&parent.name),
+                    );
+                    diags.extend(&sub_diags);
+                }
+            } else if let Some(_control) = ast.get_control(&name) {
+                if parts.len() > 1 && parts.last() != Some(&"apply") {
+                    diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: format!(
+                            "Control {} has no member {}",
+                            name.bright_blue(),
+                            parts.last().unwrap().bright_blue(),
+                        ),
+                        token: lval.token.clone(),
+                    });
+                }
+            } else {
+                diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "type {} is not defined",
+                        name.bright_blue(),
+                    ),
+                    token: lval.token.clone(),
+                });
+            }
+        }
+    };
+    diags
+}
+
+pub struct ExpressionTypeChecker {
+    //ast: &'a mut AST,
+    //ast: RefCell::<AST>,
+}
+
+impl ExpressionTypeChecker {
+    pub fn run(&self) -> (HashMap<Expression, Type>, Diagnostics) {
+        // These iterations may seem a bit odd. The reason I'm using numeric
+        // indices here is that I cannot borrow a mutable node of the AST and
+        // the AST itself at the same time, and then pass them separately into a
+        // handler function. So instead I just pass along the mutable AST
+        // together with the index of the thing I'm going to mutate within the
+        // AST. Then in the handler function, a mutable reference to the node of
+        // interest is acquired based on the index.
+        /*
+        let mut diags = Diagnostics::new();
+        for i in 0..self.ast.constants.len() {
+            diags.extend(&self.check_constant(i));
+        }
+        for i in 0..self.ast.controls.len() {
+            diags.extend(&self.check_control(i));
+        }
+        for i in 0..self.ast.parsers.len() {
+            diags.extend(&self.check_parser(i));
+        }
+        diags
+        */
+
+        todo!();
+    }
+
+    pub fn check_constant(&self, _index: usize) -> Diagnostics {
+        todo!("global constant expression type check");
+    }
+
+    pub fn check_control(&self, _index: usize) -> Diagnostics {
+        /*
+        let c = &mut self.ast.controls[index];
+        let mut diags = Diagnostics::new();
+        let names = c.names();
+        for a in &mut c.actions {
+            diags.extend(
+                &self.check_statement_block(&mut a.statement_block, &names)
+            )
+        }
+        diags
+        */
+        todo!();
+    }
+
+    pub fn check_statement_block(
+        &self,
+        _sb: &mut StatementBlock,
+        _names: &HashMap<String, NameInfo>,
+    ) -> Diagnostics {
+        todo!();
+
+        /*
+        let mut diags = Diagnostics::new();
+        for stmt in &mut sb.statements {
+            match stmt {
+                Statement::Empty => {}
+                Statement::Assignment(_, xpr) => {
+                    diags.extend(&self.check_expression(xpr, names));
+                    todo!()
+                }
+                Statement::Call(c) => { todo!() }
+                Statement::If(ifb) => { todo!() }
+                Statement::Variable(v) => { todo!() }
+                Statement::Constant(c) => { todo!() }
+            }
+        }
+        diags
+        */
+    }
+
+    pub fn check_expression(
+        &self,
+        _xpr: &mut Expression,
+        _names: &HashMap<String, NameInfo>,
+    ) -> Diagnostics {
+        /*
+        let mut diags = Diagnostics::new();
+        match &mut xpr.kind {
+            ExpressionKind::BoolLit(_) => {
+                xpr.ty = Some(Type::Bool)
+            }
+            //TODO P4 spec section 8.9.1/8.9.2
+            ExpressionKind::IntegerLit(_) => {
+                xpr.ty = Some(Type::Int(128))
+            }
+            ExpressionKind::BitLit(width, _) => {
+                xpr.ty = Some(Type::Bit(*width as usize))
+            }
+            ExpressionKind::SignedLit(width, _) => {
+                xpr.ty = Some(Type::Int(*width as usize))
+            }
+            ExpressionKind::Lvalue(lval) => {
+                //let ty = lvalue_type(lval, ast, names)
+                todo!();
+            }
+            ExpressionKind::Binary(lhs, _, rhs) => {
+                todo!();
+            }
+            ExpressionKind::Index(lval, xpr) => {
+                todo!();
+            }
+            ExpressionKind::Slice(begin, end) => {
+                todo!();
+            }
+
+        }
+        diags
+        */
+        todo!();
+    }
+
+    pub fn check_parser(&self, _index: usize) -> Diagnostics {
+        todo!("parser expression type check");
+    }
+}
+
\ No newline at end of file diff --git a/src/p4/error.rs.html b/src/p4/error.rs.html new file mode 100644 index 00000000..da4794ee --- /dev/null +++ b/src/p4/error.rs.html @@ -0,0 +1,417 @@ +error.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+
// Copyright 2022 Oxide Computer Company
+
+use crate::lexer::{Kind, Lexer, Token};
+use colored::Colorize;
+use std::fmt;
+use std::sync::Arc;
+
+#[derive(Debug)]
+pub struct SemanticError {
+    /// Token where the error was encountered
+    pub at: Token,
+
+    /// Message associated with this error.
+    pub message: String,
+
+    /// The source line the token error occured on.
+    pub source: String,
+}
+
+impl fmt::Display for SemanticError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt_common(&self.at, &self.message, &self.source, f)
+    }
+}
+
+impl std::error::Error for SemanticError {}
+
+#[derive(Debug)]
+pub struct ParserError {
+    /// Token where the error was encountered
+    pub at: Token,
+
+    /// Message associated with this error.
+    pub message: String,
+
+    /// The source line the token error occured on.
+    pub source: String,
+}
+
+impl fmt::Display for ParserError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        fmt_common(&self.at, &self.message, &self.source, f)
+    }
+}
+
+impl std::error::Error for ParserError {}
+
+#[derive(Debug)]
+pub struct TokenError {
+    /// Line where the token error was encountered.
+    pub line: usize,
+
+    /// Column where the token error was encountered.
+    pub col: usize,
+
+    /// Length of the erronious token.
+    pub len: usize,
+
+    /// The source line the token error occured on.
+    pub source: String,
+
+    /// The soruce file where the token error was encountered.
+    pub file: Arc<String>,
+}
+
+impl fmt::Display for TokenError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let at = Token {
+            kind: Kind::Eof,
+            line: self.line,
+            col: self.col,
+            file: Arc::new(self.source.clone()),
+        };
+        fmt_common(&at, "unrecognized token", &self.source, f)
+    }
+}
+
+impl std::error::Error for TokenError {}
+
+#[derive(Debug)]
+pub enum Error {
+    Lexer(TokenError),
+    Parser(ParserError),
+    Semantic(Vec<SemanticError>),
+}
+
+impl fmt::Display for Error {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match &self {
+            Self::Lexer(e) => e.fmt(f),
+            Self::Parser(e) => e.fmt(f),
+            Self::Semantic(errors) => {
+                for e in &errors[..errors.len() - 1] {
+                    e.fmt(f)?;
+                    writeln!(f)?;
+                }
+                errors[errors.len() - 1].fmt(f)?;
+                Ok(())
+            }
+        }
+    }
+}
+
+impl std::error::Error for Error {}
+
+impl From<TokenError> for Error {
+    fn from(e: TokenError) -> Self {
+        Self::Lexer(e)
+    }
+}
+
+impl From<ParserError> for Error {
+    fn from(e: ParserError) -> Self {
+        Self::Parser(e)
+    }
+}
+
+impl From<Vec<SemanticError>> for Error {
+    fn from(e: Vec<SemanticError>) -> Self {
+        Self::Semantic(e)
+    }
+}
+
+#[derive(Debug)]
+pub struct PreprocessorError {
+    /// Token where the error was encountered
+    pub line: usize,
+
+    /// Message associated with this error.
+    pub message: String,
+
+    /// The source line the token error occured on.
+    pub source: String,
+
+    /// The soruce file where the token error was encountered.
+    pub file: Arc<String>,
+}
+
+impl fmt::Display for PreprocessorError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let loc = format!("[{}]", self.line + 1).as_str().bright_red();
+        writeln!(
+            f,
+            "{}\n{} {}\n",
+            self.message.bright_white(),
+            loc,
+            *self.file,
+        )?;
+        writeln!(f, "  {}", self.source)
+    }
+}
+
+impl std::error::Error for PreprocessorError {}
+
+fn carat_line(line: &str, at: &Token) -> String {
+    // The presence of tabs makes presenting error indicators purely based
+    // on column position impossible, so here we iterrate over the existing
+    // string and mask out the non whitespace text inserting the error
+    // indicators and preserving any tab/space mixture.
+    let mut carat_line = String::new();
+    for x in line[..at.col].chars() {
+        if x.is_whitespace() {
+            carat_line.push(x);
+        } else {
+            carat_line.push(' ');
+        }
+    }
+    for x in line[at.col..].chars() {
+        if x.is_whitespace() || (Lexer::is_separator(x) && x != '.') {
+            break;
+        } else {
+            carat_line.push('^');
+        }
+    }
+    carat_line
+}
+
+fn fmt_common(
+    at: &Token,
+    message: &str,
+    source: &str,
+    f: &mut fmt::Formatter<'_>,
+) -> fmt::Result {
+    let loc = format!("[{}:{}]", at.line + 1, at.col + 1)
+        .as_str()
+        .bright_red();
+    let parts: Vec<&str> = message.split_inclusive('\n').collect();
+    let msg = parts[0];
+    let extra = if parts.len() > 1 {
+        parts[1..].join("")
+    } else {
+        "".to_string()
+    };
+    writeln!(
+        f,
+        "{}: {}{}\n{} {}\n",
+        "error".bright_red(),
+        msg.bright_white().bold(),
+        extra,
+        loc,
+        *at.file,
+    )?;
+    writeln!(f, "  {}", source)?;
+
+    let carat_line = carat_line(source, at);
+    write!(f, "  {}", carat_line.bright_red())
+}
+
\ No newline at end of file diff --git a/src/p4/hlir.rs.html b/src/p4/hlir.rs.html new file mode 100644 index 00000000..ec76a061 --- /dev/null +++ b/src/p4/hlir.rs.html @@ -0,0 +1,1035 @@ +hlir.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+
// Copyright 2022 Oxide Computer Company
+
+use crate::ast::{
+    BinOp, Constant, Control, DeclarationInfo, Expression, ExpressionKind,
+    Lvalue, NameInfo, Parser, Statement, StatementBlock, Type, AST,
+};
+use crate::check::{Diagnostic, Diagnostics, Level};
+use crate::util::resolve_lvalue;
+use std::collections::HashMap;
+
+/// The P4 high level intermediate representation (hlir) is a slight lowering of
+/// the abstract syntax tree (ast) into something a bit more concreate. In
+/// particular
+///
+/// - Types are resolved for expressions.
+/// - Lvalue names resolved to declarations.
+///
+/// The hlir maps language elements onto the corresponding type and declaration
+/// information. Langauge elements contain lexical token members which ensure
+/// hashing uniquenes.
+#[derive(Debug, Default)]
+pub struct Hlir {
+    pub expression_types: HashMap<Expression, Type>,
+    pub lvalue_decls: HashMap<Lvalue, NameInfo>,
+}
+
+pub struct HlirGenerator<'a> {
+    ast: &'a AST,
+    pub hlir: Hlir,
+    pub diags: Diagnostics,
+}
+
+impl<'a> HlirGenerator<'a> {
+    pub fn new(ast: &'a AST) -> Self {
+        Self {
+            ast,
+            hlir: Hlir::default(),
+            diags: Diagnostics::default(),
+        }
+    }
+    pub fn run(&mut self) {
+        for c in &self.ast.constants {
+            self.constant(c);
+        }
+        for c in &self.ast.controls {
+            self.control(c);
+        }
+        for p in &self.ast.parsers {
+            self.parser(p);
+        }
+    }
+
+    fn constant(&mut self, _c: &Constant) {
+        // TODO
+    }
+
+    fn control(&mut self, c: &Control) {
+        let mut names = c.names();
+        for a in &c.actions {
+            let mut local_names = names.clone();
+            local_names.extend(a.names());
+            self.statement_block(&a.statement_block, &mut local_names);
+        }
+        for t in &c.tables {
+            let mut local_names = names.clone();
+            for (lval, _match_kind) in &t.key {
+                self.lvalue(lval, &mut local_names);
+            }
+            for lval in &t.actions {
+                self.lvalue(lval, &mut local_names);
+            }
+        }
+        self.statement_block(&c.apply, &mut names);
+    }
+
+    fn statement_block(
+        &mut self,
+        sb: &StatementBlock,
+        names: &mut HashMap<String, NameInfo>,
+    ) {
+        for stmt in &sb.statements {
+            match stmt {
+                Statement::Empty => {}
+                Statement::Assignment(lval, xpr) => {
+                    self.lvalue(lval, names);
+                    self.expression(xpr, names);
+                }
+                Statement::Call(c) => {
+                    // pop the function name off the lval before resolving
+                    self.lvalue(&c.lval.pop_right(), names);
+                    for xpr in &c.args {
+                        self.expression(xpr.as_ref(), names);
+                    }
+                }
+                Statement::If(ifb) => {
+                    self.expression(ifb.predicate.as_ref(), names);
+                    self.statement_block(&ifb.block, names);
+                    for ei in &ifb.else_ifs {
+                        self.expression(ei.predicate.as_ref(), names);
+                        self.statement_block(&ei.block, names);
+                    }
+                    if let Some(eb) = &ifb.else_block {
+                        self.statement_block(eb, names);
+                    }
+                }
+                Statement::Variable(v) => {
+                    names.insert(
+                        v.name.clone(),
+                        NameInfo {
+                            ty: v.ty.clone(),
+                            decl: DeclarationInfo::Local,
+                        },
+                    );
+                    if let Some(initializer) = &v.initializer {
+                        self.expression(initializer, names);
+                    }
+                }
+                Statement::Constant(c) => {
+                    names.insert(
+                        c.name.clone(),
+                        NameInfo {
+                            ty: c.ty.clone(),
+                            decl: DeclarationInfo::Local,
+                        },
+                    );
+                    self.expression(c.initializer.as_ref(), names);
+                }
+                Statement::Transition(_t) => {
+                    //TODO
+                }
+                Statement::Return(xpr) => {
+                    if let Some(xpr) = xpr {
+                        self.expression(xpr.as_ref(), names);
+                    }
+                }
+            }
+        }
+    }
+
+    fn expression(
+        &mut self,
+        xpr: &Expression,
+        names: &mut HashMap<String, NameInfo>,
+    ) -> Option<Type> {
+        match &xpr.kind {
+            ExpressionKind::BoolLit(_) => {
+                let ty = Type::Bool;
+                self.hlir.expression_types.insert(xpr.clone(), ty.clone());
+                Some(ty)
+            }
+            ExpressionKind::IntegerLit(_) => {
+                //TODO P4 spec section 8.9.1/8.9.2
+                let ty = Type::Int(128);
+                self.hlir.expression_types.insert(xpr.clone(), ty.clone());
+                Some(ty)
+            }
+            ExpressionKind::BitLit(width, _) => {
+                let ty = Type::Bit(*width as usize);
+                self.hlir.expression_types.insert(xpr.clone(), ty.clone());
+                Some(ty)
+            }
+            ExpressionKind::SignedLit(width, _) => {
+                let ty = Type::Int(*width as usize);
+                self.hlir.expression_types.insert(xpr.clone(), ty.clone());
+                Some(ty)
+            }
+            ExpressionKind::Lvalue(lval) => {
+                let ty = self.lvalue(lval, names)?;
+                self.hlir.expression_types.insert(xpr.clone(), ty.clone());
+                Some(ty)
+            }
+            ExpressionKind::Binary(lhs, op, rhs) => {
+                self.binary_expression(xpr, lhs, rhs, op, names)
+            }
+            ExpressionKind::Index(lval, i_xpr) => {
+                if let Some(ty) = self.index(lval, i_xpr, names) {
+                    self.hlir.expression_types.insert(xpr.clone(), ty.clone());
+                    Some(ty)
+                } else {
+                    None
+                }
+            }
+            ExpressionKind::Slice(end, _begin) => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "slice cannot occur outside of an index".into(),
+                    token: end.token.clone(),
+                });
+                None
+            }
+            ExpressionKind::Call(call) => {
+                self.lvalue(&call.lval.pop_right(), names)?;
+                for arg in &call.args {
+                    self.expression(arg.as_ref(), names);
+                }
+                // TODO check extern methods in checker before getting here
+                if let Some(name_info) = names.get(call.lval.root()) {
+                    if let Type::UserDefined(typename) = &name_info.ty {
+                        if let Some(ext) = self.ast.get_extern(typename) {
+                            if let Some(m) = ext.get_method(call.lval.leaf()) {
+                                self.hlir
+                                    .expression_types
+                                    .insert(xpr.clone(), m.return_type.clone());
+                                return Some(m.return_type.clone());
+                            }
+                        }
+                    }
+                };
+                //TODO less special case-y?
+                Some(match call.lval.leaf() {
+                    "isValid" => Type::Bool,
+                    _ => Type::Void,
+                })
+            }
+            ExpressionKind::List(elements) => {
+                let mut type_elements = Vec::new();
+                for e in elements {
+                    let ty = match self.expression(e.as_ref(), names) {
+                        Some(ty) => ty,
+                        None => return None,
+                    };
+                    type_elements.push(Box::new(ty));
+                }
+                Some(Type::List(type_elements))
+            }
+        }
+    }
+
+    fn index(
+        &mut self,
+        lval: &Lvalue,
+        xpr: &Expression,
+        names: &mut HashMap<String, NameInfo>,
+    ) -> Option<Type> {
+        let base_type = match self.lvalue(lval, names) {
+            Some(ty) => ty,
+            None => return None,
+        };
+        match base_type {
+            Type::Bool => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a bool".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::State => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a state".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::Action => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index an action".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::Error => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index an error".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::Void => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a void".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::List(_) => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a list".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::Bit(width) => match &xpr.kind {
+                ExpressionKind::Slice(end, begin) => {
+                    let (begin_val, end_val) = self.slice(begin, end, width)?;
+                    let w = end_val - begin_val + 1;
+                    Some(Type::Bit(w as usize))
+                }
+                _ => {
+                    self.diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: "only slices supported as index arguments"
+                            .into(),
+                        token: lval.token.clone(),
+                    });
+                    None
+                }
+            },
+            Type::Varbit(width) => match &xpr.kind {
+                ExpressionKind::Slice(begin, end) => {
+                    let (begin_val, end_val) = self.slice(begin, end, width)?;
+                    let w = end_val - begin_val + 1;
+                    Some(Type::Varbit(w as usize))
+                }
+                _ => {
+                    self.diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: "only slices supported as index arguments"
+                            .into(),
+                        token: lval.token.clone(),
+                    });
+                    None
+                }
+            },
+            Type::Int(width) => match &xpr.kind {
+                ExpressionKind::Slice(begin, end) => {
+                    let (begin_val, end_val) = self.slice(begin, end, width)?;
+                    let w = end_val - begin_val + 1;
+                    Some(Type::Int(w as usize))
+                }
+                _ => {
+                    self.diags.push(Diagnostic {
+                        level: Level::Error,
+                        message: "only slices supported as index arguments"
+                            .into(),
+                        token: lval.token.clone(),
+                    });
+                    None
+                }
+            },
+            Type::String => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a string".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::UserDefined(_) => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a user defined type".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::ExternFunction => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index an external function".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::HeaderMethod => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a header method".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+            Type::Table => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: "cannot index a table".into(),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+        }
+    }
+
+    fn slice(
+        &mut self,
+        begin: &Expression,
+        end: &Expression,
+        width: usize,
+    ) -> Option<(i128, i128)> {
+        // According to P4-16 section 8.5, slice values must be
+        // known at compile time. For now just enfoce integer
+        // literals only, we can get fancier later with other
+        // things that can be figured out at compile time.
+        let begin_val = match &begin.kind {
+            ExpressionKind::IntegerLit(v) => *v,
+            _ => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message:
+                        "only interger literals are supported as slice bounds"
+                            .into(),
+                    token: begin.token.clone(),
+                });
+                return None;
+            }
+        };
+        let end_val = match &end.kind {
+            ExpressionKind::IntegerLit(v) => *v,
+            _ => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message:
+                        "only interger literals are supported as slice bounds"
+                            .into(),
+                    token: begin.token.clone(),
+                });
+                return None;
+            }
+        };
+        let w = width as i128;
+        if begin_val < 0 || begin_val >= w {
+            self.diags.push(Diagnostic {
+                level: Level::Error,
+                message: "slice begin value out of bounds".into(),
+                token: begin.token.clone(),
+            });
+            return None;
+        }
+        if end_val < 0 || end_val >= w {
+            self.diags.push(Diagnostic {
+                level: Level::Error,
+                message: "slice end value out of bounds".into(),
+                token: begin.token.clone(),
+            });
+            return None;
+        }
+        if begin_val >= end_val {
+            self.diags.push(Diagnostic {
+                level: Level::Error,
+                message: "slice upper bound must be \
+                    greater than the lower bound"
+                    .into(),
+                token: begin.token.clone(),
+            });
+            return None;
+        }
+        Some((begin_val, end_val))
+    }
+
+    fn lvalue(
+        &mut self,
+        lval: &Lvalue,
+        names: &mut HashMap<String, NameInfo>,
+    ) -> Option<Type> {
+        match resolve_lvalue(lval, self.ast, names) {
+            Ok(name_info) => {
+                self.hlir
+                    .lvalue_decls
+                    .insert(lval.clone(), name_info.clone());
+                Some(name_info.ty)
+            }
+            Err(e) => {
+                self.diags.push(Diagnostic {
+                    level: Level::Error,
+                    message: format!(
+                        "could not resolve lvalue: {}\n    {}",
+                        lval.name, e,
+                    ),
+                    token: lval.token.clone(),
+                });
+                None
+            }
+        }
+    }
+
+    fn binary_expression(
+        &mut self,
+        xpr: &Expression,
+        lhs: &Expression,
+        rhs: &Expression,
+        op: &BinOp,
+        names: &mut HashMap<String, NameInfo>,
+    ) -> Option<Type> {
+        let lhs_ty = match self.expression(lhs, names) {
+            Some(ty) => ty,
+            None => return None,
+        };
+
+        let rhs_ty = match self.expression(rhs, names) {
+            Some(ty) => ty,
+            None => return None,
+        };
+
+        // TODO just checking that types are the same for now.
+        if lhs_ty != rhs_ty {
+            self.diags.push(Diagnostic {
+                level: Level::Error,
+                message: format!(
+                    "cannot {} a {} and a {}",
+                    op.english_verb(),
+                    lhs_ty,
+                    rhs_ty,
+                ),
+                token: xpr.token.clone(),
+            });
+        }
+
+        self.hlir
+            .expression_types
+            .insert(xpr.clone(), lhs_ty.clone());
+        Some(lhs_ty)
+    }
+
+    fn parser(&mut self, p: &Parser) {
+        let names = p.names();
+        for s in &p.states {
+            let mut local_names = names.clone();
+            self.statement_block(&s.statements, &mut local_names);
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/p4/lexer.rs.html b/src/p4/lexer.rs.html new file mode 100644 index 00000000..1c95f6d2 --- /dev/null +++ b/src/p4/lexer.rs.html @@ -0,0 +1,2157 @@ +lexer.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+
// Copyright 2022 Oxide Computer Company
+
+use crate::error::TokenError;
+use std::fmt;
+use std::sync::Arc;
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub enum Kind {
+    //
+    // keywords
+    //
+    Const,
+    Header,
+    Typedef,
+    Control,
+    Struct,
+    Action,
+    Parser,
+    Table,
+    Size,
+    Key,
+    Exact,
+    Ternary,
+    Lpm,
+    Range,
+    Actions,
+    DefaultAction,
+    Entries,
+    In,
+    InOut,
+    Out,
+    Transition,
+    State,
+    Select,
+    Apply,
+    Package,
+    Extern,
+    If,
+    Else,
+    Return,
+
+    //
+    // types
+    //
+    Bool,
+    Error,
+    Bit,
+    Varbit,
+    Int,
+    String,
+
+    //
+    // lexical elements
+    //
+    AngleOpen,
+    AngleClose,
+    CurlyOpen,
+    CurlyClose,
+    ParenOpen,
+    ParenClose,
+    SquareOpen,
+    SquareClose,
+    Semicolon,
+    Comma,
+    Colon,
+    Underscore,
+
+    //
+    // preprocessor
+    //
+    PoundInclude,
+    PoundDefine,
+    Backslash,
+    Forwardslash,
+
+    //
+    // operators
+    //
+    DoubleEquals,
+    NotEquals,
+    Equals,
+    Plus,
+    Minus,
+    Mod,
+    Dot,
+    Mask,
+    LogicalAnd,
+    And,
+    Bang,
+    Tilde,
+    Shl,
+    Pipe,
+    Carat,
+    GreaterThanEquals,
+    LessThanEquals,
+
+    //
+    // literals
+    //
+    /// An integer literal. The following are literal examples and their
+    /// associated types.
+    ///     - `10`   : int
+    ///     - `8s10` : int<8>
+    ///     - `2s3`  : int<2>
+    ///     - `1s1`  : int<1>
+    IntLiteral(i128),
+
+    Identifier(String),
+
+    /// A bit literal. The following a literal examples and their associated
+    /// types.
+    ///     - `8w10` : bit<8>
+    ///     - `1w1`  : bit<1>
+    /// First element is number of bits (prefix before w) second element is
+    /// value (suffix after w).
+    BitLiteral(u16, u128),
+
+    /// A signed literal. The following a literal examples and their associated
+    /// types.
+    ///     - `8s10` : bit<8>
+    ///     - `1s1`  : bit<1>
+    /// First element is number of bits (prefix before w) second element is
+    /// value (suffix after w).
+    SignedLiteral(u16, i128),
+
+    TrueLiteral,
+    FalseLiteral,
+    StringLiteral(String),
+
+    /// End of file.
+    Eof,
+}
+
+impl fmt::Display for Kind {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match &self {
+            //
+            // keywords
+            //
+            Kind::Const => write!(f, "keyword const"),
+            Kind::Header => write!(f, "keyword header"),
+            Kind::Typedef => write!(f, "keyword typedef"),
+            Kind::Control => write!(f, "keyword control"),
+            Kind::Struct => write!(f, "keyword struct"),
+            Kind::Action => write!(f, "keyword action"),
+            Kind::Parser => write!(f, "keyword parser"),
+            Kind::Table => write!(f, "keyword table"),
+            Kind::Size => write!(f, "keyword size"),
+            Kind::Key => write!(f, "keyword key"),
+            Kind::Exact => write!(f, "keyword exact"),
+            Kind::Ternary => write!(f, "keyword ternary"),
+            Kind::Lpm => write!(f, "keyword lpm"),
+            Kind::Range => write!(f, "keyword range"),
+            Kind::Actions => write!(f, "keyword actions"),
+            Kind::DefaultAction => write!(f, "keyword default_action"),
+            Kind::Entries => write!(f, "keyword entries"),
+            Kind::In => write!(f, "keyword in"),
+            Kind::InOut => write!(f, "keyword in_out"),
+            Kind::Out => write!(f, "keyword out"),
+            Kind::Transition => write!(f, "keyword transition"),
+            Kind::State => write!(f, "keyword state"),
+            Kind::Select => write!(f, "keyword select"),
+            Kind::Apply => write!(f, "keyword apply"),
+            Kind::Package => write!(f, "keyword package"),
+            Kind::Extern => write!(f, "keyword extern"),
+            Kind::If => write!(f, "keyword if"),
+            Kind::Else => write!(f, "keyword else"),
+            Kind::Return => write!(f, "keyword return"),
+
+            //
+            // types
+            //
+            Kind::Bool => write!(f, "type bool"),
+            Kind::Error => write!(f, "type error"),
+            Kind::Bit => write!(f, "type bit"),
+            Kind::Varbit => write!(f, "type varbit"),
+            Kind::Int => write!(f, "type int"),
+            Kind::String => write!(f, "type string"),
+
+            //
+            // lexical elements
+            //
+            Kind::AngleOpen => write!(f, "<"),
+            Kind::AngleClose => write!(f, ">"),
+            Kind::CurlyOpen => write!(f, "{{"),
+            Kind::CurlyClose => write!(f, "}}"),
+            Kind::ParenOpen => write!(f, "("),
+            Kind::ParenClose => write!(f, ")"),
+            Kind::SquareOpen => write!(f, "["),
+            Kind::SquareClose => write!(f, "]"),
+            Kind::Semicolon => write!(f, ";"),
+            Kind::Comma => write!(f, ","),
+            Kind::Colon => write!(f, ":"),
+            Kind::Underscore => write!(f, "_"),
+
+            //
+            // preprocessor
+            //
+            Kind::PoundInclude => write!(f, "preprocessor statement #include"),
+            Kind::PoundDefine => write!(f, "preprocessor statement #define"),
+            Kind::Backslash => write!(f, "\\"),
+            Kind::Forwardslash => write!(f, "/"),
+
+            //
+            // operators
+            //
+            Kind::DoubleEquals => write!(f, "operator =="),
+            Kind::NotEquals => write!(f, "operator !="),
+            Kind::Equals => write!(f, "operator ="),
+            Kind::Plus => write!(f, "operator +"),
+            Kind::Minus => write!(f, "operator -"),
+            Kind::Mod => write!(f, "operator %"),
+            Kind::Dot => write!(f, "operator ."),
+            Kind::Mask => write!(f, "operator &&&"),
+            Kind::LogicalAnd => write!(f, "operator &&"),
+            Kind::And => write!(f, "operator &"),
+            Kind::Bang => write!(f, "operator !"),
+            Kind::Tilde => write!(f, "operator ~"),
+            Kind::Shl => write!(f, "operator <<"),
+            Kind::Pipe => write!(f, "operator |"),
+            Kind::Carat => write!(f, "operator ^"),
+            Kind::GreaterThanEquals => write!(f, "operator >="),
+            Kind::LessThanEquals => write!(f, "operator <="),
+
+            //
+            // literals
+            //
+            Kind::IntLiteral(x) => write!(f, "int literal '{}'", x),
+            Kind::Identifier(x) => write!(f, "identifier '{}'", x),
+            Kind::BitLiteral(w, x) => write!(f, "bit literal '{}w{}'", w, x),
+            Kind::SignedLiteral(w, x) => {
+                write!(f, "signed literal {}s{}", w, x)
+            }
+            Kind::TrueLiteral => write!(f, "boolean literal true"),
+            Kind::FalseLiteral => write!(f, "boolean literal false"),
+            Kind::StringLiteral(x) => write!(f, "string literal '{}'", x),
+
+            Kind::Eof => write!(f, "end of file"),
+        }
+    }
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub struct Token {
+    /// The kind of token this is.
+    pub kind: Kind,
+
+    /// Line number of this token.
+    pub line: usize,
+
+    /// Column number of the first character in this token.
+    pub col: usize,
+
+    /// The file this token came from.
+    pub file: Arc<String>,
+}
+
+impl fmt::Display for Token {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}:{}: {:?}", self.line, self.col, self.kind)
+    }
+}
+
+pub struct Lexer<'a> {
+    pub line: usize,
+    pub col: usize,
+    pub show_tokens: bool,
+
+    pub(crate) lines: Vec<&'a str>,
+    cursor: &'a str,
+    file: Arc<String>,
+}
+
+impl<'a> Lexer<'a> {
+    pub fn new(lines: Vec<&'a str>, filename: Arc<String>) -> Self {
+        if lines.is_empty() {
+            return Self {
+                cursor: "",
+                line: 0,
+                col: 0,
+                lines,
+                show_tokens: false,
+                file: filename,
+            };
+        }
+
+        let start = lines[0];
+
+        Self {
+            cursor: start,
+            line: 0,
+            col: 0,
+            lines,
+            show_tokens: false,
+            file: filename,
+        }
+    }
+
+    #[allow(clippy::should_implement_trait)]
+    pub fn next(&mut self) -> Result<Token, TokenError> {
+        let token = self.do_next()?;
+        if self.show_tokens {
+            println!("{}", token);
+        }
+        Ok(token)
+    }
+    fn do_next(&mut self) -> Result<Token, TokenError> {
+        self.check_end_of_line();
+
+        if self.line >= self.lines.len() {
+            return Ok(Token {
+                kind: Kind::Eof,
+                col: self.col,
+                line: self.line,
+                file: self.file.clone(),
+            });
+        }
+
+        while self.skip_whitespace() {}
+        while self.skip_comment() {}
+        if self.line >= self.lines.len() {
+            return Ok(Token {
+                kind: Kind::Eof,
+                col: self.col,
+                line: self.line,
+                file: self.file.clone(),
+            });
+        }
+        self.skip_whitespace();
+        //self.skip_comment();
+
+        if let Some(t) = self.match_token("#include", Kind::PoundInclude) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("#define", Kind::PoundDefine) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("&&&", Kind::Mask) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("inout", Kind::InOut) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("in", Kind::In) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("out", Kind::Out) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("transition", Kind::Transition) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("state", Kind::State) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("select", Kind::Select) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("apply", Kind::Apply) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("package", Kind::Package) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("extern", Kind::Extern) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("if", Kind::If) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("else", Kind::Else) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("return", Kind::Return) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("&&", Kind::LogicalAnd) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("&", Kind::And) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("==", Kind::DoubleEquals) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("!=", Kind::NotEquals) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("|", Kind::Pipe) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("<<", Kind::Shl) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("<", Kind::AngleOpen) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(">", Kind::AngleClose) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(">=", Kind::GreaterThanEquals) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(">=", Kind::LessThanEquals) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(">", Kind::AngleClose) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("{", Kind::CurlyOpen) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("}", Kind::CurlyClose) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("(", Kind::ParenOpen) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(")", Kind::ParenClose) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("[", Kind::SquareOpen) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("]", Kind::SquareClose) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("+", Kind::Plus) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("-", Kind::Minus) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("%", Kind::Mod) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("=", Kind::Equals) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(":", Kind::Colon) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("_", Kind::Underscore) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(";", Kind::Semicolon) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(".", Kind::Dot) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("^", Kind::Carat) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token(",", Kind::Comma) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("!", Kind::Bang) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("~", Kind::Tilde) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("\\", Kind::Backslash) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("/", Kind::Forwardslash) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("bool", Kind::Bool) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("varbit", Kind::Varbit) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("bit", Kind::Bit) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("int", Kind::Int) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("typedef", Kind::Typedef) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("header", Kind::Header) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("const", Kind::Const) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("control", Kind::Control) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("struct", Kind::Struct) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("actions", Kind::Actions) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("default_action", Kind::DefaultAction)
+        {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("action", Kind::Action) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("parser", Kind::Parser) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("entries", Kind::Entries) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("table", Kind::Table) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("size", Kind::Size) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("key", Kind::Key) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("exact", Kind::Exact) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("ternary", Kind::Ternary) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("lpm", Kind::Lpm) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("range", Kind::Range) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("true", Kind::TrueLiteral) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_token("false", Kind::FalseLiteral) {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_integer() {
+            return Ok(t);
+        }
+
+        if let Some(t) = self.match_identifier() {
+            return Ok(t);
+        }
+
+        let len = self.skip_token();
+
+        Err(TokenError {
+            line: self.line,
+            col: self.col - len,
+            source: self.lines[self.line].into(),
+            file: self.file.clone(),
+            len,
+        })
+    }
+
+    fn match_identifier(&mut self) -> Option<Token> {
+        let tok = self.peek_token();
+        let len = tok.len();
+        if tok.is_empty() {
+            return None;
+        }
+        let mut chars = tok.chars();
+        if !Self::is_letter(chars.next().unwrap()) {
+            return None;
+        }
+        for c in chars {
+            if !Self::is_letter(c) && !c.is_ascii_digit() {
+                return None;
+            }
+        }
+        let token = Token {
+            kind: Kind::Identifier(tok.into()),
+            col: self.col,
+            line: self.line,
+            file: self.file.clone(),
+        };
+        self.col += len;
+        self.cursor = &self.cursor[len..];
+        Some(token)
+    }
+
+    fn is_letter(c: char) -> bool {
+        c.is_ascii_alphabetic() || c == '_'
+    }
+
+    fn parse_bitsized(
+        &self,
+        tok: &str,
+        n: usize,
+        ctor: fn(u16, u128) -> Kind,
+    ) -> Option<Token> {
+        let bits = match tok[..n].parse::<u16>() {
+            Ok(n) => n,
+            Err(_) => return None,
+        };
+        let value = if tok[n + 1..].starts_with("0x") {
+            match u128::from_str_radix(&tok[n + 3..], 16) {
+                Ok(n) => n,
+                Err(_) => return None,
+            }
+        } else {
+            match tok[n + 1..].parse::<u128>() {
+                Ok(n) => n,
+                Err(_) => return None,
+            }
+        };
+        let token = Token {
+            kind: ctor(bits, value),
+            col: self.col,
+            line: self.line,
+            file: self.file.clone(),
+        };
+        Some(token)
+    }
+
+    // TODO copy pasta from parse_bitsized, but no trait to hold on to for
+    // from_str_radix to generalize
+    fn parse_intsized(
+        &self,
+        tok: &str,
+        n: usize,
+        ctor: fn(u16, i128) -> Kind,
+    ) -> Option<Token> {
+        let bits = match tok[..n].parse::<u16>() {
+            Ok(n) => n,
+            Err(_) => return None,
+        };
+        let value = if tok[n + 1..].starts_with("0x") {
+            match i128::from_str_radix(&tok[n + 3..], 16) {
+                Ok(n) => n,
+                Err(_) => return None,
+            }
+        } else {
+            match tok[n + 1..].parse::<i128>() {
+                Ok(n) => n,
+                Err(_) => return None,
+            }
+        };
+        let token = Token {
+            kind: ctor(bits, value),
+            col: self.col,
+            line: self.line,
+            file: self.file.clone(),
+        };
+        Some(token)
+    }
+
+    fn match_integer(&mut self) -> Option<Token> {
+        let tok = self.peek_token();
+        let len = tok.len();
+        if tok.is_empty() {
+            return None;
+        }
+
+        let mut chars = tok.chars();
+        let leading = if let Some('w') = chars.nth(1) {
+            Some(1)
+        } else if let Some('w') = chars.next() {
+            Some(2)
+        } else if let Some('w') = chars.next() {
+            Some(3)
+        } else {
+            None
+        };
+
+        if let Some(n) = leading {
+            match self.parse_bitsized(tok, n, Kind::BitLiteral) {
+                Some(token) => {
+                    self.col += len;
+                    self.cursor = &self.cursor[len..];
+                    return Some(token);
+                }
+                None => return None,
+            }
+        }
+
+        let mut chars = tok.chars();
+        let leading = if let Some('s') = chars.nth(1) {
+            Some(1)
+        } else if let Some('s') = chars.next() {
+            Some(2)
+        } else if let Some('s') = chars.next() {
+            Some(3)
+        } else {
+            None
+        };
+
+        if let Some(n) = leading {
+            match self.parse_intsized(tok, n, Kind::SignedLiteral) {
+                Some(token) => {
+                    self.col += len;
+                    self.cursor = &self.cursor[len..];
+                    return Some(token);
+                }
+                None => return None,
+            }
+        }
+
+        let value = if let Some(tok) = tok.strip_prefix("0x") {
+            let chars = tok.chars();
+            for c in chars {
+                if !c.is_ascii_hexdigit() {
+                    return None;
+                }
+            }
+            i128::from_str_radix(tok, 16).expect("parse hex int")
+        } else {
+            let chars = tok.chars();
+            for c in chars {
+                if !c.is_ascii_digit() {
+                    return None;
+                }
+            }
+            tok.parse::<i128>().expect("parse int")
+        };
+        let token = Token {
+            kind: Kind::IntLiteral(value),
+            col: self.col,
+            line: self.line,
+            file: self.file.clone(),
+        };
+        self.col += len;
+        self.cursor = &self.cursor[len..];
+        Some(token)
+    }
+
+    pub fn check_end_of_line(&mut self) -> bool {
+        let mut end = false;
+        while self.cursor.is_empty() {
+            end = true;
+            self.line += 1;
+            self.col = 0;
+            if self.line < self.lines.len() {
+                self.cursor = self.lines[self.line];
+            } else {
+                break;
+            }
+        }
+        end
+    }
+
+    fn skip_whitespace(&mut self) -> bool {
+        let mut chars = self.cursor.chars();
+        let mut skipped = false;
+        while match chars.next() {
+            Some(n) => n.is_whitespace(),
+            None => false,
+        } {
+            skipped = true;
+            self.cursor = &self.cursor[1..];
+            self.col += 1;
+            self.check_end_of_line();
+        }
+        skipped
+    }
+
+    fn skip_token(&mut self) -> usize {
+        let mut len = 0;
+        let mut chars = self.cursor.chars();
+        while match chars.next() {
+            Some(n) => !n.is_whitespace() && !Self::is_separator(n),
+            None => false,
+        } {
+            len += 1
+        }
+        self.col += len;
+        self.cursor = &self.cursor[len..];
+        len
+    }
+
+    fn skip_comment(&mut self) -> bool {
+        if self.cursor.starts_with("//") {
+            self.skip_line_comment();
+            return true;
+        }
+        if self.cursor.starts_with("/*") {
+            self.skip_block_comment();
+            return true;
+        }
+        false
+    }
+
+    fn skip_block_comment(&mut self) {
+        let mut chars = self.cursor.chars();
+        match chars.next() {
+            Some('/') => {}
+            _ => return,
+        }
+        match chars.next() {
+            Some('*') => {}
+            _ => return,
+        }
+        self.cursor = &self.cursor[2..];
+        loop {
+            loop {
+                match chars.next() {
+                    Some('*') => {
+                        self.cursor = &self.cursor[1..];
+                        match chars.next() {
+                            Some('/') => {
+                                self.col += 1;
+                                self.cursor = &self.cursor[1..];
+                                self.check_end_of_line();
+                                self.skip_whitespace();
+                                return;
+                            }
+                            _ => {
+                                if self.check_end_of_line() {
+                                    break;
+                                }
+                                self.cursor = &self.cursor[1..];
+                                continue;
+                            }
+                        }
+                    }
+                    None => {
+                        self.skip_whitespace();
+                        if self.check_end_of_line() {
+                            break;
+                        }
+                    }
+                    _ => {
+                        self.cursor = &self.cursor[1..];
+                        continue;
+                    }
+                }
+            }
+            chars = self.cursor.chars();
+        }
+    }
+
+    fn skip_line_comment(&mut self) {
+        let mut chars = self.cursor.chars();
+        match chars.next() {
+            Some('/') => {}
+            _ => return,
+        }
+        match chars.next() {
+            Some('/') => {}
+            _ => return,
+        }
+        let mut len = 2;
+        while !matches!(chars.next(), Some('\r') | Some('\n') | None) {
+            len += 1
+        }
+        self.col += len;
+        self.cursor = &self.cursor[len..];
+        self.check_end_of_line();
+        self.skip_whitespace();
+    }
+
+    fn match_token(&mut self, text: &str, kind: Kind) -> Option<Token> {
+        let tok = self.peek_token();
+        let len = text.len();
+        if tok.to_lowercase() == text.to_lowercase() {
+            let token = Token {
+                kind,
+                col: self.col,
+                line: self.line,
+                file: self.file.clone(),
+            };
+            self.col += len;
+            self.cursor = &self.cursor[len..];
+            Some(token)
+        } else {
+            None
+        }
+    }
+
+    fn peek_token(&self) -> &str {
+        let mut chars = self.cursor.chars();
+
+        // recognize non-space separators that should be tokens themselves
+        match chars.next() {
+            Some(';') => return &self.cursor[..1],
+            Some(',') => return &self.cursor[..1],
+            Some('+') => return &self.cursor[..1],
+            Some('-') => return &self.cursor[..1],
+            Some('(') => return &self.cursor[..1],
+            Some(')') => return &self.cursor[..1],
+            Some('{') => return &self.cursor[..1],
+            Some('}') => return &self.cursor[..1],
+            Some('[') => return &self.cursor[..1],
+            Some(']') => return &self.cursor[..1],
+            Some('.') => return &self.cursor[..1],
+            Some(':') => return &self.cursor[..1],
+            Some('*') => return &self.cursor[..1],
+            Some('|') => return &self.cursor[..1],
+            Some('~') => return &self.cursor[..1],
+            Some('^') => return &self.cursor[..1],
+            Some('\\') => return &self.cursor[..1],
+            Some('/') => return &self.cursor[..1],
+            Some('!') => match chars.next() {
+                Some('=') => return &self.cursor[..2],
+                _ => return &self.cursor[..1],
+            },
+            Some('=') => match chars.next() {
+                Some('=') => return &self.cursor[..2],
+                _ => return &self.cursor[..1],
+            },
+            Some('>') => match chars.next() {
+                Some('=') => return &self.cursor[..2],
+                _ => return &self.cursor[..1],
+            },
+            Some('<') => match chars.next() {
+                Some('=') => return &self.cursor[..2],
+                Some('<') => return &self.cursor[..2],
+                _ => return &self.cursor[..1],
+            },
+            Some('&') => match chars.next() {
+                Some('&') => match chars.next() {
+                    Some('&') => return &self.cursor[..3],
+                    _ => return &self.cursor[..2],
+                },
+                _ => return &self.cursor[..1],
+            },
+            _ => {}
+        };
+
+        let mut len = 1;
+        while match chars.next() {
+            Some(n) => !Self::is_separator(n),
+            None => false,
+        } {
+            len += 1
+        }
+        &self.cursor[..len]
+    }
+
+    pub(crate) fn is_separator(c: char) -> bool {
+        if c.is_whitespace() {
+            return true;
+        }
+        if c == ',' {
+            return true;
+        }
+        if c == ':' {
+            return true;
+        }
+        if c == ';' {
+            return true;
+        }
+        if c == '*' {
+            return true;
+        }
+        if c == '+' {
+            return true;
+        }
+        if c == '-' {
+            return true;
+        }
+        if c == '<' {
+            return true;
+        }
+        if c == '>' {
+            return true;
+        }
+        if c == '{' {
+            return true;
+        }
+        if c == '}' {
+            return true;
+        }
+        if c == '=' {
+            return true;
+        }
+        if c == '(' {
+            return true;
+        }
+        if c == ')' {
+            return true;
+        }
+        if c == '[' {
+            return true;
+        }
+        if c == ']' {
+            return true;
+        }
+        if c == '&' {
+            return true;
+        }
+        if c == '.' {
+            return true;
+        }
+        if c == '!' {
+            return true;
+        }
+        if c == '^' {
+            return true;
+        }
+        if c == '|' {
+            return true;
+        }
+        if c == '~' {
+            return true;
+        }
+        if c == '\\' {
+            return true;
+        }
+        if c == '/' {
+            return true;
+        }
+        false
+    }
+}
+
\ No newline at end of file diff --git a/src/p4/lib.rs.html b/src/p4/lib.rs.html new file mode 100644 index 00000000..97eb0d69 --- /dev/null +++ b/src/p4/lib.rs.html @@ -0,0 +1,23 @@ +lib.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
// Copyright 2022 Oxide Computer Company
+
+pub mod ast;
+pub mod check;
+pub mod error;
+pub mod hlir;
+pub mod lexer;
+pub mod parser;
+pub mod preprocessor;
+pub mod util;
+
\ No newline at end of file diff --git a/src/p4/parser.rs.html b/src/p4/parser.rs.html new file mode 100644 index 00000000..7a6da364 --- /dev/null +++ b/src/p4/parser.rs.html @@ -0,0 +1,3739 @@ +parser.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+1706
+1707
+1708
+1709
+1710
+1711
+1712
+1713
+1714
+1715
+1716
+1717
+1718
+1719
+1720
+1721
+1722
+1723
+1724
+1725
+1726
+1727
+1728
+1729
+1730
+1731
+1732
+1733
+1734
+1735
+1736
+1737
+1738
+1739
+1740
+1741
+1742
+1743
+1744
+1745
+1746
+1747
+1748
+1749
+1750
+1751
+1752
+1753
+1754
+1755
+1756
+1757
+1758
+1759
+1760
+1761
+1762
+1763
+1764
+1765
+1766
+1767
+1768
+1769
+1770
+1771
+1772
+1773
+1774
+1775
+1776
+1777
+1778
+1779
+1780
+1781
+1782
+1783
+1784
+1785
+1786
+1787
+1788
+1789
+1790
+1791
+1792
+1793
+1794
+1795
+1796
+1797
+1798
+1799
+1800
+1801
+1802
+1803
+1804
+1805
+1806
+1807
+1808
+1809
+1810
+1811
+1812
+1813
+1814
+1815
+1816
+1817
+1818
+1819
+1820
+1821
+1822
+1823
+1824
+1825
+1826
+1827
+1828
+1829
+1830
+1831
+1832
+1833
+1834
+1835
+1836
+1837
+1838
+1839
+1840
+1841
+1842
+1843
+1844
+1845
+1846
+1847
+1848
+1849
+1850
+1851
+1852
+1853
+1854
+1855
+1856
+1857
+1858
+1859
+1860
+1861
+1862
+1863
+1864
+1865
+1866
+1867
+1868
+
// Copyright 2022 Oxide Computer Company
+
+use crate::ast::{
+    self, Action, ActionParameter, ActionRef, BinOp, Call, ConstTableEntry,
+    Constant, Control, ControlParameter, Direction, ElseIfBlock, Expression,
+    ExpressionKind, Extern, ExternMethod, Header, HeaderMember, IfBlock,
+    KeySetElement, KeySetElementValue, Lvalue, MatchKind, Package,
+    PackageInstance, PackageParameter, Select, SelectElement, State, Statement,
+    StatementBlock, Struct, StructMember, Table, Transition, Type, Typedef,
+    Variable, AST,
+};
+use crate::error::{Error, ParserError};
+use crate::lexer::{self, Kind, Lexer, Token};
+use colored::Colorize;
+
+/// This is a recurisve descent parser for the P4 language.
+pub struct Parser<'a> {
+    lexer: Lexer<'a>,
+    backlog: Vec<Token>,
+}
+
+impl<'a> Parser<'a> {
+    pub fn new(lexer: Lexer<'a>) -> Self {
+        Parser {
+            lexer,
+            backlog: Vec::new(),
+        }
+    }
+
+    pub fn run(&mut self, ast: &mut AST) -> Result<(), Error> {
+        let mut gp = GlobalParser::new(self);
+        gp.run(ast)?;
+        Ok(())
+    }
+
+    pub fn next_token(&mut self) -> Result<Token, Error> {
+        if self.backlog.is_empty() {
+            Ok(self.lexer.next()?)
+        } else {
+            Ok(self.backlog.pop().unwrap())
+        }
+    }
+
+    /// Consume a series of tokens constituting a path. Returns the first
+    /// non-path element found.
+    #[allow(dead_code)]
+    fn parse_path(&mut self) -> Result<(String, Token), Error> {
+        let mut path = String::new();
+        loop {
+            let token = self.next_token()?;
+            match token.kind {
+                lexer::Kind::Identifier(ref s) => path += s,
+                lexer::Kind::Dot => path += ".",
+                lexer::Kind::Forwardslash => path += "/",
+                lexer::Kind::Backslash => path += "\\",
+                _ => return Ok((path, token)),
+            }
+        }
+    }
+
+    fn expect_token(&mut self, expected: lexer::Kind) -> Result<(), Error> {
+        let token = self.next_token()?;
+        if token.kind != expected {
+            return Err(ParserError {
+                at: token.clone(),
+                message: format!(
+                    "Found {} expected '{}'.",
+                    token.kind, expected,
+                ),
+                source: self.lexer.lines[token.line].into(),
+            }
+            .into());
+        }
+        Ok(())
+    }
+
+    fn parse_identifier(
+        &mut self,
+        what: &str,
+    ) -> Result<(String, Token), Error> {
+        let token = self.next_token()?;
+        Ok((
+            match token.kind {
+                Kind::Identifier(ref name) => name.into(),
+                Kind::Apply => {
+                    // sometimes apply is not the keyword but a method called
+                    // against tables.
+                    "apply".into()
+                }
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                            "Found {} expected {}.",
+                            token.kind, what,
+                        ),
+                        source: self.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            },
+            token,
+        ))
+    }
+
+    fn parse_lvalue(&mut self, what: &str) -> Result<Lvalue, Error> {
+        let mut name = String::new();
+        let mut first_token = None;
+        loop {
+            let (ident, tk) = self.parse_identifier(what)?;
+            match first_token {
+                Some(_) => {}
+                None => first_token = Some(tk),
+            }
+            name = name + &ident;
+            let token = self.next_token()?;
+            match token.kind {
+                lexer::Kind::Dot => name += ".",
+                _ => {
+                    self.backlog.push(token);
+                    break;
+                }
+            }
+        }
+        Ok(Lvalue {
+            name,
+            token: first_token.unwrap(),
+        })
+    }
+
+    fn parse_type(&mut self) -> Result<(Type, Token), Error> {
+        let token = self.next_token()?;
+        Ok((
+            match &token.kind {
+                lexer::Kind::Bool => Type::Bool,
+                lexer::Kind::Error => Type::Error,
+                lexer::Kind::String => Type::String,
+                lexer::Kind::Bit => {
+                    Type::Bit(self.parse_optional_width_parameter()?)
+                }
+
+                lexer::Kind::Varbit => {
+                    Type::Varbit(self.parse_optional_width_parameter()?)
+                }
+
+                lexer::Kind::Int => {
+                    Type::Int(self.parse_optional_width_parameter()?)
+                }
+
+                lexer::Kind::Identifier(name) => {
+                    Type::UserDefined(name.clone())
+                }
+
+                _ => {
+                    return Err(
+                        ParserError {
+                            at: token.clone(),
+                            message: format!(
+                                "Found {} expected type.",
+                                token.kind,
+                            ),
+                            source: self.lexer.lines[token.line].into(),
+                        }
+                        .into(),
+                    )
+                }
+            },
+            token,
+        ))
+    }
+
+    fn parse_optional_width_parameter(&mut self) -> Result<usize, Error> {
+        let token = self.next_token()?;
+        match &token.kind {
+            lexer::Kind::AngleOpen => {}
+            _ => {
+                // no argument implies a size of 1 (7.1.6.2)
+                self.backlog.push(token);
+                return Ok(1);
+            }
+        }
+
+        let token = self.next_token()?;
+        let width = match &token.kind {
+            lexer::Kind::IntLiteral(w) => w,
+            _ => {
+                return Err(ParserError {
+                    at: token.clone(),
+                    message: format!(
+                        "Integer literal expected for width parameter, \
+                        found {}",
+                        token.kind,
+                    ),
+                    source: self.lexer.lines[token.line].into(),
+                }
+                .into())
+            }
+        };
+
+        self.expect_token(Kind::AngleClose)?;
+
+        Ok(*width as usize)
+    }
+
+    pub fn parse_direction(&mut self) -> Result<(Direction, Token), Error> {
+        let token = self.next_token()?;
+        match token.kind {
+            lexer::Kind::In => Ok((Direction::In, token)),
+            lexer::Kind::Out => Ok((Direction::Out, token)),
+            lexer::Kind::InOut => Ok((Direction::InOut, token)),
+            _ => {
+                self.backlog.push(token.clone());
+                Ok((Direction::Unspecified, token))
+            }
+        }
+    }
+
+    pub fn parse_variable(&mut self) -> Result<Variable, Error> {
+        let (ty, tytk) = self.parse_type()?;
+        let token = self.next_token()?;
+
+        // check for constructor
+        let parameters = if token.kind == lexer::Kind::ParenOpen {
+            self.backlog.push(token);
+            self.parse_parameters()?
+        } else {
+            self.backlog.push(token);
+            Vec::new()
+        };
+
+        let (name, _) = self.parse_identifier("variable name")?;
+
+        let token = self.next_token()?;
+        // check for initializer
+        if token.kind == lexer::Kind::Equals {
+            let initializer = self.parse_expression()?;
+            self.expect_token(lexer::Kind::Semicolon)?;
+            Ok(Variable {
+                ty,
+                name,
+                initializer: Some(initializer),
+                parameters,
+                token: tytk,
+            })
+        } else {
+            self.backlog.push(token);
+            self.expect_token(lexer::Kind::Semicolon)?;
+            Ok(Variable {
+                ty,
+                name,
+                initializer: None,
+                parameters,
+                token: tytk,
+            })
+        }
+    }
+
+    pub fn parse_constant(&mut self) -> Result<Constant, Error> {
+        let (ty, _) = self.parse_type()?;
+        let (name, _) = self.parse_identifier("constant name")?;
+        self.expect_token(lexer::Kind::Equals)?;
+        let initializer = self.parse_expression()?;
+        self.expect_token(lexer::Kind::Semicolon)?;
+        Ok(Constant {
+            ty,
+            name,
+            initializer,
+        })
+    }
+
+    pub fn parse_expression(&mut self) -> Result<Box<Expression>, Error> {
+        let mut ep = ExpressionParser::new(self);
+        ep.run()
+    }
+
+    pub fn parse_keyset(&mut self) -> Result<Vec<KeySetElement>, Error> {
+        let token = self.next_token()?;
+        match token.kind {
+            lexer::Kind::ParenOpen => {
+                // handle tuple set below
+            }
+            lexer::Kind::Underscore => {
+                return Ok(vec![KeySetElement {
+                    value: KeySetElementValue::DontCare,
+                    token,
+                }]);
+            }
+            _ => {
+                self.backlog.push(token.clone());
+                let mut ep = ExpressionParser::new(self);
+                let expr = ep.run()?;
+                return Ok(vec![KeySetElement {
+                    value: KeySetElementValue::Expression(expr),
+                    token,
+                }]);
+            }
+        }
+
+        let mut elements = Vec::new();
+
+        loop {
+            let token = self.next_token()?;
+            // handle dont-care special case
+            match token.kind {
+                lexer::Kind::Underscore => {
+                    elements.push(KeySetElement {
+                        value: KeySetElementValue::DontCare,
+                        token: token.clone(),
+                    });
+                    let token = self.next_token()?;
+                    match token.kind {
+                        lexer::Kind::Comma => continue,
+                        lexer::Kind::ParenClose => return Ok(elements),
+                        _ => {
+                            return Err(ParserError {
+                                at: token.clone(),
+                                message: format!(
+                                    "Found {} expected: \
+                                    comma or paren close after \
+                                    dont-care match",
+                                    token.kind,
+                                ),
+                                source: self.lexer.lines[token.line].into(),
+                            }
+                            .into())
+                        }
+                    }
+                }
+                _ => {
+                    self.backlog.push(token);
+                }
+            }
+            let mut ep = ExpressionParser::new(self);
+            let expr = ep.run()?;
+            let token = self.next_token()?;
+            match token.kind {
+                lexer::Kind::Comma => {
+                    elements.push(KeySetElement {
+                        value: KeySetElementValue::Expression(expr),
+                        token: token.clone(),
+                    });
+                    continue;
+                }
+                lexer::Kind::ParenClose => {
+                    elements.push(KeySetElement {
+                        value: KeySetElementValue::Expression(expr),
+                        token,
+                    });
+                    return Ok(elements);
+                }
+                lexer::Kind::Mask => {
+                    let mut ep = ExpressionParser::new(self);
+                    let mask_expr = ep.run()?;
+                    elements.push(KeySetElement {
+                        value: KeySetElementValue::Masked(expr, mask_expr),
+                        token: token.clone(),
+                    });
+                    let token = self.next_token()?;
+                    match token.kind {
+                        lexer::Kind::Comma => continue,
+                        lexer::Kind::ParenClose => return Ok(elements),
+                        _ => {
+                            return Err(ParserError {
+                                at: token.clone(),
+                                message: format!(
+                                    "Found {} expected: \
+                                    comma or close paren after mask",
+                                    token.kind,
+                                ),
+                                source: self.lexer.lines[token.line].into(),
+                            }
+                            .into())
+                        }
+                    }
+                }
+                //TODO Default case
+                //TODO DontCare case
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                            "Found {} expected: keyset expression",
+                            token.kind,
+                        ),
+                        source: self.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+    }
+
+    // parse a tuple of expressions (<expr>, <expr> ...), used for both tuples
+    // and function call sites
+    pub fn parse_expr_parameters(
+        &mut self,
+    ) -> Result<Vec<Box<Expression>>, Error> {
+        let mut result = Vec::new();
+
+        self.expect_token(lexer::Kind::ParenOpen)?;
+
+        loop {
+            let token = self.next_token()?;
+
+            // check if we've reached the end of the parameters
+            if token.kind == lexer::Kind::ParenClose {
+                break;
+            }
+
+            // if the token was not a closing paren push it into the backlog and
+            // carry on.
+            self.backlog.push(token);
+
+            // parameters are a comma delimited list of expressions
+            let mut ep = ExpressionParser::new(self);
+            let expr = ep.run()?;
+            result.push(expr);
+
+            let token = self.next_token()?;
+            match token.kind {
+                lexer::Kind::Comma => continue,
+                lexer::Kind::ParenClose => break,
+                _ => {
+                    // assume this token is a part of the next expression and
+                    // carry on
+                    self.backlog.push(token);
+                    continue;
+                }
+            }
+        }
+
+        Ok(result)
+    }
+
+    fn try_parse_binop(&mut self) -> Result<Option<BinOp>, Error> {
+        let token = self.next_token()?;
+        match token.kind {
+            lexer::Kind::GreaterThanEquals => Ok(Some(BinOp::Geq)),
+            lexer::Kind::AngleClose => Ok(Some(BinOp::Gt)),
+            lexer::Kind::LessThanEquals => Ok(Some(BinOp::Leq)),
+            lexer::Kind::AngleOpen => Ok(Some(BinOp::Lt)),
+            lexer::Kind::NotEquals => Ok(Some(BinOp::NotEq)),
+            lexer::Kind::DoubleEquals => Ok(Some(BinOp::Eq)),
+            lexer::Kind::Plus => Ok(Some(BinOp::Add)),
+            lexer::Kind::Minus => Ok(Some(BinOp::Subtract)),
+            lexer::Kind::Mod => Ok(Some(BinOp::Mod)),
+            lexer::Kind::Mask => Ok(Some(BinOp::Mask)),
+            lexer::Kind::And => Ok(Some(BinOp::BitAnd)),
+            lexer::Kind::Pipe => Ok(Some(BinOp::BitOr)),
+            lexer::Kind::Carat => Ok(Some(BinOp::Xor)),
+
+            // TODO other binops
+            _ => {
+                self.backlog.push(token);
+                Ok(None)
+            }
+        }
+    }
+
+    pub fn parse_statement_block(&mut self) -> Result<StatementBlock, Error> {
+        let mut result = StatementBlock::default();
+
+        self.expect_token(lexer::Kind::CurlyOpen)?;
+
+        loop {
+            let token = self.next_token()?;
+
+            // check if we've reached the end of the statements
+            match token.kind {
+                lexer::Kind::CurlyClose => break,
+
+                // variable declaration / initialization
+                lexer::Kind::Bool
+                | lexer::Kind::Error
+                | lexer::Kind::Bit
+                | lexer::Kind::Int
+                | lexer::Kind::String => {
+                    self.backlog.push(token);
+                    let var = self.parse_variable()?;
+                    result.statements.push(Statement::Variable(var));
+                }
+
+                // constant declaration / initialization
+                lexer::Kind::Const => {
+                    let c = self.parse_constant()?;
+                    //result.constants.push(c);
+                    result.statements.push(Statement::Constant(c));
+                }
+
+                lexer::Kind::Identifier(_)
+                | lexer::Kind::If
+                | lexer::Kind::Return => {
+                    // push the identifier token into the backlog and run the
+                    // statement parser
+                    self.backlog.push(token);
+                    let mut sp = StatementParser::new(self);
+                    let stmt = sp.run()?;
+                    result.statements.push(stmt);
+                }
+                lexer::Kind::Transition => {
+                    result
+                        .statements
+                        .push(Statement::Transition(self.parse_transition()?));
+                }
+
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                        "Found {} expected variable, constant, statement or \
+                        instantiation.",
+                        token.kind,
+                    ),
+                        source: self.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+
+        Ok(result)
+    }
+
+    pub fn parse_transition(&mut self) -> Result<Transition, Error> {
+        let token = self.next_token()?;
+
+        match token.kind {
+            lexer::Kind::Select => {
+                let mut sp = SelectParser::new(self);
+                let select = sp.run()?;
+                Ok(Transition::Select(select))
+            }
+            lexer::Kind::Identifier(ref name) => {
+                let result = Transition::Reference(Lvalue {
+                    name: name.clone(),
+                    token: token.clone(),
+                });
+                self.expect_token(lexer::Kind::Semicolon)?;
+                Ok(result)
+            }
+            _ => Err(ParserError {
+                at: token.clone(),
+                message: format!(
+                    "Found {}: expected select or identifier",
+                    token.kind,
+                ),
+                source: self.lexer.lines[token.line].into(),
+            }
+            .into()),
+        }
+    }
+
+    pub fn parse_parameters(&mut self) -> Result<Vec<ControlParameter>, Error> {
+        let mut result = Vec::new();
+        self.expect_token(lexer::Kind::ParenOpen)?;
+
+        loop {
+            let token = self.next_token()?;
+
+            // check if we've reached the end of the parameters
+            if token.kind == lexer::Kind::ParenClose {
+                break;
+            }
+
+            // if the token was not a closing paren push it into the backlog and
+            // carry on.
+            self.backlog.push(token);
+
+            // parse a parameter
+            let (direction, dtk) = self.parse_direction()?;
+            let (ty, ttk) = self.parse_type()?;
+            let (name, ntk) = self.parse_identifier("parameter name")?;
+            let token = self.next_token()?;
+            if token.kind == lexer::Kind::ParenClose {
+                result.push(ControlParameter {
+                    direction,
+                    ty,
+                    name,
+                    dir_token: dtk,
+                    ty_token: ttk,
+                    name_token: ntk,
+                });
+                break;
+            }
+            self.backlog.push(token.clone());
+            self.expect_token(lexer::Kind::Comma)?;
+
+            result.push(ControlParameter {
+                direction,
+                ty,
+                name,
+                dir_token: dtk,
+                ty_token: ttk,
+                name_token: ntk,
+            });
+        }
+
+        Ok(result)
+    }
+
+    pub fn parse_type_parameters(&mut self) -> Result<Vec<String>, Error> {
+        let mut result = Vec::new();
+
+        self.expect_token(lexer::Kind::AngleOpen)?;
+
+        loop {
+            let (ident, _) = self.parse_identifier("type parameter name")?;
+            result.push(ident);
+
+            let token = self.next_token()?;
+            match token.kind {
+                lexer::Kind::AngleClose => break,
+                lexer::Kind::Comma => continue,
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                            "Found {} expected: type parameter",
+                            token.kind,
+                        ),
+                        source: self.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+
+        Ok(result)
+    }
+}
+
+/// Top level parser for parsing elements are global scope.
+pub struct GlobalParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> GlobalParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&'b mut self, ast: &mut AST) -> Result<(), Error> {
+        loop {
+            match self.parser.next_token() {
+                Ok(token) => {
+                    if token.kind == lexer::Kind::Eof {
+                        break;
+                    }
+                    self.handle_token(token, ast)?;
+                }
+                Err(e) => return Err(e),
+            };
+        }
+
+        Ok(())
+    }
+
+    pub fn handle_token(
+        &mut self,
+        token: Token,
+        ast: &mut AST,
+    ) -> Result<(), Error> {
+        match token.kind {
+            lexer::Kind::Const => self.handle_const_decl(ast)?,
+            lexer::Kind::Header => self.handle_header_decl(ast)?,
+            lexer::Kind::Struct => self.handle_struct_decl(ast)?,
+            lexer::Kind::Typedef => self.handle_typedef(ast)?,
+            lexer::Kind::Control => self.handle_control(ast)?,
+            lexer::Kind::Parser => self.handle_parser(ast, token)?,
+            lexer::Kind::Package => self.handle_package(ast)?,
+            lexer::Kind::Extern => self.handle_extern(ast)?,
+            lexer::Kind::Identifier(typ) => {
+                self.handle_package_instance(typ, ast)?
+            }
+            _ => {}
+        }
+        Ok(())
+    }
+
+    pub fn handle_const_decl(&mut self, ast: &mut AST) -> Result<(), Error> {
+        // the first token after const must be a type
+        let (ty, _) = self.parser.parse_type()?;
+
+        // next comes a name
+        let (name, _) = self.parser.parse_identifier("constant name")?;
+
+        // then an initializer
+        self.parser.expect_token(lexer::Kind::Equals)?;
+        let initializer = self.parser.parse_expression()?;
+
+        ast.constants.push(Constant {
+            ty,
+            name,
+            initializer,
+        });
+
+        Ok(())
+    }
+
+    pub fn handle_header_decl(&mut self, ast: &mut AST) -> Result<(), Error> {
+        // the first token of a header must be an identifier
+        let (name, _) = self.parser.parse_identifier("header name")?;
+
+        // next the header body starts with an open curly brace
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        let mut header = Header::new(name);
+
+        // iterate over header members
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the header body
+            if token.kind == lexer::Kind::CurlyClose {
+                break;
+            }
+
+            // if the token was not a closing curly bracket push it into the
+            // backlog and carry on.
+            self.parser.backlog.push(token);
+
+            // parse a header member
+            let (ty, tyt) = self.parser.parse_type()?;
+            let (name, _) =
+                self.parser.parse_identifier("header member name")?;
+            self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+            header.members.push(HeaderMember {
+                ty,
+                name,
+                token: tyt,
+            });
+        }
+
+        ast.headers.push(header);
+
+        Ok(())
+    }
+
+    pub fn handle_struct_decl(&mut self, ast: &mut AST) -> Result<(), Error> {
+        // the first token of a struct must be an identifier
+        let (name, _) = self.parser.parse_identifier("struct name")?;
+
+        // next the struct body starts with an open curly brace
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        let mut p4_struct = Struct::new(name);
+
+        // iterate over struct members
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the struct body
+            if token.kind == lexer::Kind::CurlyClose {
+                break;
+            }
+
+            // if the token was not a closing curly bracket push it into the
+            // backlog and carry on.
+            self.parser.backlog.push(token);
+
+            // parse a struct member
+            let (ty, tyt) = self.parser.parse_type()?;
+            let (name, _) =
+                self.parser.parse_identifier("struct member name")?;
+            self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+            p4_struct.members.push(StructMember {
+                ty,
+                name,
+                token: tyt,
+            });
+        }
+
+        ast.structs.push(p4_struct);
+
+        Ok(())
+    }
+
+    pub fn handle_typedef(&mut self, ast: &mut AST) -> Result<(), Error> {
+        // first token must be a type
+        let (ty, _) = self.parser.parse_type()?;
+
+        // next must be a name
+        let (name, _) = self.parser.parse_identifier("typedef name")?;
+
+        self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+        ast.typedefs.push(Typedef { ty, name });
+
+        Ok(())
+    }
+
+    pub fn handle_control(&mut self, ast: &mut AST) -> Result<(), Error> {
+        let mut cp = ControlParser::new(self.parser);
+        let control = cp.run()?;
+        ast.controls.push(control);
+        Ok(())
+    }
+
+    pub fn handle_parser(
+        &mut self,
+        ast: &mut AST,
+        start: Token,
+    ) -> Result<(), Error> {
+        let mut pp = ParserParser::new(self.parser, start);
+        let parser = pp.run()?;
+        ast.parsers.push(parser);
+        Ok(())
+    }
+
+    pub fn handle_package(&mut self, ast: &mut AST) -> Result<(), Error> {
+        let (name, _) = self.parser.parse_identifier("package name")?;
+        let mut pkg = Package::new(name);
+
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::AngleOpen => {
+                self.parser.backlog.push(token);
+                pkg.type_parameters = self.parser.parse_type_parameters()?;
+            }
+            _ => {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        self.parse_package_parameters(&mut pkg)?;
+        self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+        ast.packages.push(pkg);
+
+        Ok(())
+    }
+
+    pub fn handle_extern(&mut self, ast: &mut AST) -> Result<(), Error> {
+        let (name, token) = self.parser.parse_identifier("extern name")?;
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        let mut ext = Extern {
+            name,
+            token,
+            methods: Vec::new(),
+        };
+
+        // parse functions
+        loop {
+            let (return_type, _) = self.parser.parse_type()?;
+            let (name, _) =
+                self.parser.parse_identifier("extern function name")?;
+
+            let token = self.parser.next_token()?;
+            let type_parameters = if token.kind == lexer::Kind::AngleOpen {
+                self.parser.backlog.push(token);
+                self.parser.parse_type_parameters()?
+            } else {
+                self.parser.backlog.push(token);
+                Vec::new()
+            };
+            let parameters = self.parser.parse_parameters()?;
+            self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+            ext.methods.push(ExternMethod {
+                return_type,
+                name,
+                type_parameters,
+                parameters,
+            });
+
+            let token = self.parser.next_token()?;
+            if token.kind == lexer::Kind::CurlyClose {
+                break;
+            } else {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        ast.externs.push(ext);
+
+        Ok(())
+    }
+
+    pub fn parse_package_parameters(
+        &mut self,
+        pkg: &mut Package,
+    ) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::ParenOpen)?;
+        loop {
+            let token = self.parser.next_token()?;
+            match token.kind {
+                lexer::Kind::ParenClose => break,
+                lexer::Kind::Comma => continue,
+                lexer::Kind::Identifier(type_name) => {
+                    let mut parameter = PackageParameter::new(type_name);
+                    let token = self.parser.next_token()?;
+                    self.parser.backlog.push(token.clone());
+                    if token.kind == lexer::Kind::AngleOpen {
+                        parameter.type_parameters =
+                            self.parser.parse_type_parameters()?;
+                    }
+                    let (name, _) = self
+                        .parser
+                        .parse_identifier("package parameter name")?;
+                    parameter.name = name;
+                    pkg.parameters.push(parameter);
+                }
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                            "Found {} expected package parameter.",
+                            token.kind,
+                        ),
+                        source: self.parser.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    pub fn handle_package_instance(
+        &mut self,
+        typ: String,
+        ast: &mut AST,
+    ) -> Result<(), Error> {
+        let mut inst = PackageInstance::new(typ);
+
+        self.parser.expect_token(lexer::Kind::ParenOpen)?;
+        loop {
+            let (arg, _) = self.parser.parse_identifier("package name")?;
+            self.parser.expect_token(lexer::Kind::ParenOpen)?;
+            self.parser.expect_token(lexer::Kind::ParenClose)?;
+            inst.parameters.push(arg);
+            let token = self.parser.next_token()?;
+            match token.kind {
+                lexer::Kind::ParenClose => break,
+                _ => {
+                    self.parser.backlog.push(token);
+                    self.parser.expect_token(lexer::Kind::Comma)?;
+                    continue;
+                }
+            }
+        }
+
+        let (name, _) =
+            self.parser.parse_identifier("package instance name")?;
+        inst.name = name;
+        self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+        ast.package_instance = Some(inst);
+        Ok(())
+    }
+}
+
+/// Parser for parsing control definitions
+pub struct ControlParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> ControlParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Control, Error> {
+        let (name, _) = self.parser.parse_identifier("control name")?;
+        let mut control = Control::new(name);
+
+        //
+        // check for type parameters
+        //
+
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::AngleOpen => {
+                self.parser.backlog.push(token);
+                control.type_parameters =
+                    self.parser.parse_type_parameters()?;
+            }
+            _ => {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        //
+        // control parameters
+        //
+
+        control.parameters = self.parser.parse_parameters()?;
+
+        //
+        // check for declaration only (e.g. no body)
+        //
+
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::Semicolon => return Ok(control),
+            _ => {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        //
+        // parse body of the control
+        //
+
+        self.parse_body(&mut control)?;
+
+        Ok(control)
+    }
+
+    pub fn parse_body(&mut self, control: &mut Control) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        // iterate over body statements
+        loop {
+            let token = self.parser.next_token()?;
+
+            match token.kind {
+                lexer::Kind::CurlyClose => break,
+                lexer::Kind::Action => self.parse_action(control)?,
+                lexer::Kind::Table => self.parse_table(control)?,
+                lexer::Kind::Apply => self.parse_apply(control)?,
+                lexer::Kind::Const => {
+                    let c = self.parser.parse_constant()?;
+                    control.constants.push(c);
+                }
+                lexer::Kind::Identifier(_) => {
+                    self.parser.backlog.push(token);
+                    let v = self.parser.parse_variable()?;
+                    control.variables.push(v);
+                }
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                            "Found {} expected: \
+                            {}, {}, {}, or end of {}",
+                            token.kind.to_string().bright_blue(),
+                            "action".bright_blue(),
+                            "table".bright_blue(),
+                            "apply".bright_blue(),
+                            "control".bright_blue()
+                        ),
+                        source: self.parser.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_action(&mut self, control: &mut Control) -> Result<(), Error> {
+        let mut ap = ActionParser::new(self.parser);
+        let action = ap.run()?;
+        control.actions.push(action);
+
+        Ok(())
+    }
+
+    pub fn parse_table(&mut self, control: &mut Control) -> Result<(), Error> {
+        let mut tp = TableParser::new(self.parser);
+        let table = tp.run()?;
+        control.tables.push(table);
+
+        Ok(())
+    }
+
+    pub fn parse_apply(&mut self, control: &mut Control) -> Result<(), Error> {
+        control.apply = self.parser.parse_statement_block()?;
+
+        Ok(())
+    }
+}
+
+pub struct ActionParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> ActionParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Action, Error> {
+        let (name, _) = self.parser.parse_identifier("action name")?;
+        let mut action = Action::new(name);
+
+        self.parse_parameters(&mut action)?;
+        //self.parse_body(&mut action)?;
+        action.statement_block = self.parser.parse_statement_block()?;
+
+        Ok(action)
+    }
+
+    pub fn parse_parameters(
+        &mut self,
+        action: &mut Action,
+    ) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::ParenOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the parameters
+            if token.kind == lexer::Kind::ParenClose {
+                break;
+            }
+
+            // if the token was not a closing paren push it into the backlog and
+            // carry on.
+            self.parser.backlog.push(token);
+
+            // parse a parameter
+            let direction = match self.parser.parse_direction() {
+                Ok((dir, _)) => dir,
+                Err(_) => Direction::Unspecified,
+            };
+            let (ty, ty_token) = self.parser.parse_type()?;
+            let (name, name_token) =
+                self.parser.parse_identifier("action parameter name")?;
+            let token = self.parser.next_token()?;
+            if token.kind == lexer::Kind::ParenClose {
+                action.parameters.push(ActionParameter {
+                    direction,
+                    ty,
+                    name,
+                    ty_token,
+                    name_token,
+                });
+                break;
+            }
+            self.parser.backlog.push(token);
+            self.parser.expect_token(lexer::Kind::Comma)?;
+
+            action.parameters.push(ActionParameter {
+                direction,
+                ty,
+                name,
+                ty_token,
+                name_token,
+            });
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_sized_variable(
+        &mut self,
+        _ty: Type,
+    ) -> Result<Variable, Error> {
+        todo!();
+    }
+}
+
+pub struct TableParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> TableParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Table, Error> {
+        let (name, tk) = self.parser.parse_identifier("table name")?;
+        let mut table = Table::new(name, tk);
+
+        self.parse_body(&mut table)?;
+
+        Ok(table)
+    }
+
+    pub fn parse_body(&mut self, table: &mut Table) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+            match token.kind {
+                lexer::Kind::CurlyClose => break,
+                lexer::Kind::Key => self.parse_key(table)?,
+                lexer::Kind::Actions => self.parse_actions(table)?,
+                lexer::Kind::DefaultAction => {
+                    self.parse_default_action(table)?
+                }
+                lexer::Kind::Size => {
+                    self.parser.expect_token(lexer::Kind::Equals)?;
+                    let token = self.parser.next_token()?;
+                    let size = match token.kind {
+                        lexer::Kind::IntLiteral(x) => x,
+                        _ => {
+                            return Err(ParserError {
+                                at: token.clone(),
+                                message: format!(
+                                    "Found {} expected constant integer",
+                                    token.kind,
+                                ),
+                                source: self.parser.lexer.lines[token.line]
+                                    .into(),
+                            }
+                            .into())
+                        }
+                    };
+                    self.parser.expect_token(lexer::Kind::Semicolon)?;
+                    table.size = size as usize;
+                }
+                lexer::Kind::Const => {
+                    let token = self.parser.next_token()?;
+                    match token.kind {
+                        lexer::Kind::Entries => self.parse_entries(table)?,
+                        //TODO need handle regular constants?
+                        _ => {
+                            return Err(ParserError {
+                                at: token.clone(),
+                                message: format!(
+                                    "Found {} expected: entries",
+                                    token.kind,
+                                ),
+                                source: self.parser.lexer.lines[token.line]
+                                    .into(),
+                            }
+                            .into())
+                        }
+                    }
+                }
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                        "Found {} expected: key, actions, entries or end of \
+                            table",
+                        token.kind,
+                    ),
+                        source: self.parser.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_key(&mut self, table: &mut Table) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::Equals)?;
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the key block
+            if token.kind == lexer::Kind::CurlyClose {
+                break;
+            }
+            self.parser.backlog.push(token);
+
+            let key = self.parser.parse_lvalue("table key")?;
+            self.parser.expect_token(lexer::Kind::Colon)?;
+            let match_kind = self.parse_match_kind()?;
+            self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+            table.key.push((key, match_kind));
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_match_kind(&mut self) -> Result<MatchKind, Error> {
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::Exact => Ok(MatchKind::Exact),
+            lexer::Kind::Ternary => Ok(MatchKind::Ternary),
+            lexer::Kind::Lpm => Ok(MatchKind::LongestPrefixMatch),
+            lexer::Kind::Range => Ok(MatchKind::Range),
+            _ => Err(ParserError {
+                at: token.clone(),
+                message: format!(
+                    "Found {} expected match kind: exact, ternary or lpm",
+                    token.kind,
+                ),
+                source: self.parser.lexer.lines[token.line].into(),
+            }
+            .into()),
+        }
+    }
+
+    pub fn parse_actions(&mut self, table: &mut Table) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::Equals)?;
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the actions block
+            if token.kind == lexer::Kind::CurlyClose {
+                break;
+            }
+            self.parser.backlog.push(token);
+
+            let (action_name, atk) =
+                self.parser.parse_identifier("action name")?;
+            self.parser.expect_token(lexer::Kind::Semicolon)?;
+
+            table.actions.push(Lvalue {
+                name: action_name,
+                token: atk,
+            });
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_default_action(
+        &mut self,
+        table: &mut Table,
+    ) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::Equals)?;
+        (table.default_action, _) =
+            self.parser.parse_identifier("default action name")?;
+        self.parser.expect_token(lexer::Kind::Semicolon)?;
+        Ok(())
+    }
+
+    pub fn parse_entries(&mut self, table: &mut Table) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::Equals)?;
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+            match token.kind {
+                lexer::Kind::CurlyClose => break,
+                _ => {
+                    self.parser.backlog.push(token);
+                    let entry = self.parse_entry()?;
+                    table.const_entries.push(entry);
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_entry(&mut self) -> Result<ConstTableEntry, Error> {
+        let keyset = self.parser.parse_keyset()?;
+        self.parser.expect_token(lexer::Kind::Colon)?;
+        let action = self.parse_actionref()?;
+        self.parser.expect_token(lexer::Kind::Semicolon)?;
+        Ok(ConstTableEntry { keyset, action })
+    }
+
+    pub fn parse_actionref(&mut self) -> Result<ActionRef, Error> {
+        let (name, aref_tk) = self.parser.parse_identifier("action name")?;
+        let token = self.parser.next_token()?;
+        let mut actionref = ActionRef::new(name, aref_tk);
+        match token.kind {
+            lexer::Kind::Semicolon => Ok(actionref),
+            lexer::Kind::ParenOpen => {
+                let token = self.parser.next_token()?;
+                if token.kind == lexer::Kind::ParenClose {
+                    return Ok(actionref);
+                } else {
+                    self.parser.backlog.push(token);
+                }
+                let mut args = Vec::new();
+                loop {
+                    let mut ep = ExpressionParser::new(self.parser);
+                    let expr = ep.run()?;
+                    let token = self.parser.next_token()?;
+                    match token.kind {
+                        lexer::Kind::Comma => {
+                            args.push(expr);
+                            continue;
+                        }
+                        lexer::Kind::ParenClose => {
+                            args.push(expr);
+                            actionref.parameters = args;
+                            return Ok(actionref);
+                        }
+                        _ => {
+                            return Err(ParserError {
+                                at: token.clone(),
+                                message: format!(
+                                    "Found {} expected: action parameter",
+                                    token.kind,
+                                ),
+                                source: self.parser.lexer.lines[token.line]
+                                    .into(),
+                            }
+                            .into())
+                        }
+                    }
+                }
+            }
+            _ => Err(ParserError {
+                at: token.clone(),
+                message: format!(
+                    "Found {} expected: reference to action, or \
+                        parameterized reference to action",
+                    token.kind,
+                ),
+                source: self.parser.lexer.lines[token.line].into(),
+            }
+            .into()),
+        }
+    }
+}
+
+pub struct StatementParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> StatementParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Statement, Error> {
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::If => {
+                let mut iep = IfElseParser::new(self.parser);
+                return iep.run();
+            }
+            lexer::Kind::Return => {
+                let token = self.parser.next_token()?;
+                if token.kind == lexer::Kind::Semicolon {
+                    return Ok(Statement::Return(None));
+                } else {
+                    self.parser.backlog.push(token);
+                    let mut ep = ExpressionParser::new(self.parser);
+                    return Ok(Statement::Return(Some(ep.run()?)));
+                }
+            }
+            _ => {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        // wrap the identifier as an lvalue, consuming any dot
+        // concatenated references
+        let lval = self.parser.parse_lvalue("identifier")?;
+
+        let token = self.parser.next_token()?;
+        let statement = match token.kind {
+            lexer::Kind::Equals => self.parse_assignment(lval)?,
+            lexer::Kind::ParenOpen => {
+                self.parser.backlog.push(token);
+                self.parse_call(lval)?
+            }
+            lexer::Kind::AngleOpen => self.parse_parameterized_call(lval)?,
+            _ => {
+                return Err(ParserError {
+                    at: token.clone(),
+                    message: format!(
+                        "Found {} expected assignment or function/method call.",
+                        token.kind,
+                    ),
+                    source: self.parser.lexer.lines[token.line].into(),
+                }
+                .into())
+            }
+        };
+
+        self.parser.expect_token(lexer::Kind::Semicolon)?;
+        Ok(statement)
+    }
+
+    pub fn parse_assignment(
+        &mut self,
+        lval: Lvalue,
+    ) -> Result<Statement, Error> {
+        let mut ep = ExpressionParser::new(self.parser);
+        let expression = ep.run()?;
+        Ok(Statement::Assignment(lval, expression))
+    }
+
+    pub fn parse_call(&mut self, lval: Lvalue) -> Result<Statement, Error> {
+        let args = self.parser.parse_expr_parameters()?;
+        Ok(Statement::Call(Call { lval, args }))
+    }
+
+    pub fn parse_parameterized_call(
+        &mut self,
+        _lval: Lvalue,
+    ) -> Result<Statement, Error> {
+        todo!();
+    }
+}
+
+pub struct IfElseParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> IfElseParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Statement, Error> {
+        let predicate = self.parse_predicate()?;
+        let block = self.parser.parse_statement_block()?;
+        let mut blk = IfBlock {
+            predicate,
+            block,
+            else_ifs: Vec::new(),
+            else_block: None,
+        };
+
+        // check for else / else if
+        loop {
+            let token = self.parser.next_token()?;
+            if token.kind == lexer::Kind::Else {
+                let token = self.parser.next_token()?;
+                if token.kind == lexer::Kind::If {
+                    // else if
+                    let predicate = self.parse_predicate()?;
+                    let block = self.parser.parse_statement_block()?;
+                    blk.else_ifs.push(ElseIfBlock { predicate, block });
+                } else {
+                    // else
+                    self.parser.backlog.push(token);
+                    let block = self.parser.parse_statement_block()?;
+                    blk.else_block = Some(block);
+                    break;
+                }
+            } else {
+                self.parser.backlog.push(token);
+                break;
+            }
+        }
+
+        Ok(Statement::If(blk))
+    }
+
+    fn parse_predicate(&mut self) -> Result<Box<Expression>, Error> {
+        self.parser.expect_token(lexer::Kind::ParenOpen)?;
+        let mut ep = ExpressionParser::new(self.parser);
+        let xpr = ep.run()?;
+        self.parser.expect_token(lexer::Kind::ParenClose)?;
+        Ok(xpr)
+    }
+}
+
+pub struct ExpressionParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> ExpressionParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Box<Expression>, Error> {
+        let token = self.parser.next_token()?;
+        let lhs = match token.kind {
+            lexer::Kind::TrueLiteral => {
+                Expression::new(token.clone(), ExpressionKind::BoolLit(true))
+            }
+            lexer::Kind::FalseLiteral => {
+                Expression::new(token.clone(), ExpressionKind::BoolLit(false))
+            }
+            lexer::Kind::IntLiteral(value) => Expression::new(
+                token.clone(),
+                ExpressionKind::IntegerLit(value),
+            ),
+            lexer::Kind::BitLiteral(width, value) => Expression::new(
+                token.clone(),
+                ExpressionKind::BitLit(width, value),
+            ),
+            lexer::Kind::SignedLiteral(width, value) => Expression::new(
+                token.clone(),
+                ExpressionKind::SignedLit(width, value),
+            ),
+            lexer::Kind::Identifier(_) => {
+                self.parser.backlog.push(token.clone());
+                let lval = self.parser.parse_lvalue("identifier")?;
+
+                let this_token = token.clone();
+                let token = self.parser.next_token()?;
+
+                // check for index
+                if token.kind == lexer::Kind::SquareOpen {
+                    let mut xp = ExpressionParser::new(self.parser);
+                    let xpr = xp.run()?;
+                    // check for slice
+                    let slice_token = self.parser.next_token()?;
+                    if slice_token.kind == lexer::Kind::Colon {
+                        let mut xp = ExpressionParser::new(self.parser);
+                        let slice_xpr = xp.run()?;
+                        self.parser.expect_token(lexer::Kind::SquareClose)?;
+                        Expression::new(
+                            token,
+                            ExpressionKind::Index(
+                                lval,
+                                Expression::new(
+                                    slice_token,
+                                    ExpressionKind::Slice(xpr, slice_xpr),
+                                ),
+                            ),
+                        )
+                    } else {
+                        self.parser.backlog.push(token.clone());
+                        self.parser.expect_token(lexer::Kind::SquareClose)?;
+                        Expression::new(token, ExpressionKind::Index(lval, xpr))
+                    }
+                }
+                // check for call
+                else if token.kind == lexer::Kind::ParenOpen {
+                    self.parser.backlog.push(token.clone());
+                    let args = self.parser.parse_expr_parameters()?;
+                    Expression::new(
+                        token,
+                        ExpressionKind::Call(Call { lval, args }),
+                    )
+                }
+                // if it's not an index and it's not a call, it's an lvalue
+                else {
+                    self.parser.backlog.push(token);
+                    Expression::new(this_token, ExpressionKind::Lvalue(lval))
+                }
+            }
+            lexer::Kind::CurlyOpen => {
+                let mut elements = Vec::new();
+                loop {
+                    let token = self.parser.next_token()?;
+                    if token.kind == lexer::Kind::Comma {
+                        continue;
+                    }
+                    if token.kind == lexer::Kind::CurlyClose {
+                        break;
+                    }
+                    self.parser.backlog.push(token);
+                    let mut xp = ExpressionParser::new(self.parser);
+                    let xpr = xp.run()?;
+                    elements.push(xpr);
+                }
+                Expression::new(token.clone(), ExpressionKind::List(elements))
+            }
+            _ => {
+                return Err(ParserError {
+                    at: token.clone(),
+                    message: format!(
+                        "Found {} expected expression.",
+                        token.kind,
+                    ),
+                    source: self.parser.lexer.lines[token.line].into(),
+                }
+                .into())
+            }
+        };
+
+        // check for binary operator
+        match self.parser.try_parse_binop()? {
+            Some(op) => {
+                // recurse to rhs
+                let mut ep = ExpressionParser::new(self.parser);
+                let rhs = ep.run()?;
+                Ok(Expression::new(token, ExpressionKind::Binary(lhs, op, rhs)))
+            }
+            None => Ok(lhs),
+        }
+    }
+}
+
+/// Parser for parsing parser definitions
+pub struct ParserParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+    start: Token,
+}
+
+impl<'a, 'b> ParserParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>, start: Token) -> Self {
+        Self { parser, start }
+    }
+
+    pub fn run(&mut self) -> Result<ast::Parser, Error> {
+        let (name, _) = self.parser.parse_identifier("parser name")?;
+        let mut parser = ast::Parser::new(name, self.start.clone());
+
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::AngleOpen => {
+                self.parser.backlog.push(token);
+                parser.type_parameters = self.parser.parse_type_parameters()?;
+            }
+            _ => {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        self.parse_parameters(&mut parser)?;
+
+        let token = self.parser.next_token()?;
+        match token.kind {
+            lexer::Kind::Semicolon => {
+                parser.decl_only = true;
+                return Ok(parser);
+            }
+            _ => {
+                self.parser.backlog.push(token);
+            }
+        }
+
+        self.parse_body(&mut parser)?;
+
+        Ok(parser)
+    }
+
+    pub fn parse_parameters(
+        &mut self,
+        parser: &mut ast::Parser,
+    ) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::ParenOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the parameters
+            if token.kind == lexer::Kind::ParenClose {
+                break;
+            }
+
+            // if the token was not a closing paren push it into the backlog and
+            // carry on.
+            self.parser.backlog.push(token);
+
+            // parse a parameter
+            let (direction, dtk) = self.parser.parse_direction()?;
+            let (ty, ttk) = self.parser.parse_type()?;
+            let (name, ntk) = self.parser.parse_identifier("parameter name")?;
+            let token = self.parser.next_token()?;
+            if token.kind == lexer::Kind::ParenClose {
+                parser.parameters.push(ControlParameter {
+                    direction,
+                    ty,
+                    name,
+                    dir_token: dtk,
+                    ty_token: ttk,
+                    name_token: ntk,
+                });
+                break;
+            }
+            self.parser.backlog.push(token.clone());
+            self.parser.expect_token(lexer::Kind::Comma)?;
+
+            parser.parameters.push(ControlParameter {
+                direction,
+                ty,
+                name,
+                dir_token: dtk,
+                ty_token: ttk,
+                name_token: ntk,
+            });
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_body(
+        &mut self,
+        parser: &mut ast::Parser,
+    ) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        // iterate over body statements
+        loop {
+            let token = self.parser.next_token()?;
+
+            match token.kind {
+                lexer::Kind::CurlyClose => break,
+                lexer::Kind::State => self.parse_state(parser)?,
+                _ => {
+                    return Err(ParserError {
+                        at: token.clone(),
+                        message: format!(
+                            "Found {} expected: state or nd of parser",
+                            token.kind,
+                        ),
+                        source: self.parser.lexer.lines[token.line].into(),
+                    }
+                    .into())
+                }
+            }
+        }
+
+        Ok(())
+    }
+
+    pub fn parse_state(
+        &mut self,
+        parser: &mut ast::Parser,
+    ) -> Result<(), Error> {
+        let mut sp = StateParser::new(self.parser);
+        let state = sp.run()?;
+        parser.states.push(state);
+
+        Ok(())
+    }
+}
+
+pub struct StateParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> StateParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<State, Error> {
+        let (name, tk) = self.parser.parse_identifier("state name")?;
+        let mut state = State::new(name, tk);
+
+        self.parse_body(&mut state)?;
+
+        Ok(state)
+    }
+
+    pub fn parse_body(&mut self, state: &mut State) -> Result<(), Error> {
+        state.statements = self.parser.parse_statement_block()?;
+        Ok(())
+    }
+}
+
+pub struct SelectParser<'a, 'b> {
+    parser: &'b mut Parser<'a>,
+}
+
+impl<'a, 'b> SelectParser<'a, 'b> {
+    pub fn new(parser: &'b mut Parser<'a>) -> Self {
+        Self { parser }
+    }
+
+    pub fn run(&mut self) -> Result<Select, Error> {
+        let mut select = Select {
+            parameters: self.parser.parse_expr_parameters()?,
+            ..Default::default()
+        };
+        self.parse_body(&mut select)?;
+        Ok(select)
+    }
+
+    pub fn parse_body(&mut self, select: &mut Select) -> Result<(), Error> {
+        self.parser.expect_token(lexer::Kind::CurlyOpen)?;
+
+        loop {
+            let token = self.parser.next_token()?;
+
+            // check if we've reached the end of the parameters
+            if token.kind == lexer::Kind::CurlyClose {
+                break;
+            }
+            self.parser.backlog.push(token);
+
+            let keyset = self.parser.parse_keyset()?;
+            self.parser.expect_token(lexer::Kind::Colon)?;
+            let (name, _) = self.parser.parse_identifier("select parameter")?;
+            self.parser.expect_token(lexer::Kind::Semicolon)?;
+            select.elements.push(SelectElement { keyset, name });
+        }
+
+        Ok(())
+    }
+}
+
\ No newline at end of file diff --git a/src/p4/preprocessor.rs.html b/src/p4/preprocessor.rs.html new file mode 100644 index 00000000..2845f80a --- /dev/null +++ b/src/p4/preprocessor.rs.html @@ -0,0 +1,399 @@ +preprocessor.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+
// Copyright 2022 Oxide Computer Company
+
+use crate::error::PreprocessorError;
+use std::fmt::Write;
+use std::sync::Arc;
+
+#[derive(Clone, Debug)]
+struct Macro {
+    pub name: String,
+    pub body: String,
+}
+
+#[derive(Debug, Default)]
+pub struct PreprocessorResult {
+    pub elements: PreprocessorElements,
+    pub lines: Vec<String>,
+}
+
+#[derive(Debug, Default)]
+pub struct PreprocessorElements {
+    pub includes: Vec<String>,
+}
+
+pub fn run(
+    source: &str,
+    filename: Arc<String>,
+) -> Result<PreprocessorResult, PreprocessorError> {
+    let mut result = PreprocessorResult::default();
+    let mut macros_to_process = Vec::new();
+    let mut current_macro: Option<Macro> = None;
+
+    //
+    // first break the source up into lines
+    //
+
+    let lines: Vec<&str> = source.lines().collect();
+    let mut new_lines: Vec<&str> = Vec::new();
+
+    //
+    // process each line of the input
+    //
+
+    for (i, line) in lines.iter().enumerate() {
+        //
+        // see if we're in a macro
+        //
+
+        match current_macro {
+            None => {}
+            Some(ref mut m) => {
+                if !line.ends_with('\\') {
+                    write!(m.body, "\n{}", line).unwrap();
+                    macros_to_process.push(m.clone());
+                    current_macro = None;
+                } else {
+                    write!(m.body, "\n{}", &line[..line.len() - 1]).unwrap();
+                }
+                continue;
+            }
+        }
+
+        //
+        // collect includes
+        //
+
+        if line.starts_with("#include") {
+            process_include(i, line, &mut result, &filename)?;
+            new_lines.push("");
+            continue;
+        }
+
+        //
+        // collect macros
+        //
+
+        if line.starts_with("#define") {
+            let (name, value) = process_macro_begin(i, line, &filename)?;
+            let m = Macro { name, body: value };
+            if !line.ends_with('\\') {
+                macros_to_process.push(m.clone());
+                current_macro = None;
+            } else {
+                current_macro = Some(m);
+            }
+            new_lines.push("");
+            continue;
+        }
+
+        //
+        // if we are here, this is not a line to be pre-processed
+        //
+
+        new_lines.push(line)
+    }
+
+    //println!("macros to process\n{:#?}", macros_to_process);
+
+    //
+    // process macros
+    //
+    for line in &new_lines {
+        let mut l = line.to_string();
+        for m in &macros_to_process {
+            l = l.replace(&m.name, &m.body);
+        }
+        result.lines.push(l);
+    }
+
+    Ok(result)
+}
+
+fn process_include(
+    i: usize,
+    line: &str,
+    result: &mut PreprocessorResult,
+    filename: &Arc<String>,
+) -> Result<(), PreprocessorError> {
+    let (begin, end) = if let Some(begin) = line.find('<') {
+        match line[begin..].find('>') {
+            Some(end) => (begin + 1, begin + end),
+            None => {
+                return Err(PreprocessorError {
+                    line: i,
+                    message: "Unterminated '<'".into(),
+                    source: line.to_string(),
+                    file: filename.clone(),
+                })
+            }
+        }
+    } else if let Some(begin) = line.find('"') {
+        match line[begin..].find('"') {
+            Some(end) => (begin + 1, begin + end),
+            None => {
+                return Err(PreprocessorError {
+                    line: i,
+                    message: "Unterminated '\"'".into(),
+                    source: line.to_string(),
+                    file: filename.clone(),
+                })
+            }
+        }
+    } else {
+        return Err(PreprocessorError {
+            line: i,
+            message: "Invalid #include".into(),
+            source: line.to_string(),
+            file: filename.clone(),
+        });
+    };
+
+    if end < line.len() {
+        for c in line[end + 1..].chars() {
+            if !c.is_whitespace() {
+                return Err(PreprocessorError {
+                    line: i,
+                    message: format!(
+                        "Unexpected character after #include '{}'",
+                        c,
+                    ),
+                    source: line.to_string(),
+                    file: filename.clone(),
+                });
+            }
+        }
+    }
+    result.elements.includes.push(line[begin..end].into());
+
+    Ok(())
+}
+
+fn process_macro_begin(
+    i: usize,
+    line: &str,
+    filename: &Arc<String>,
+) -> Result<(String, String), PreprocessorError> {
+    let mut parts = line.split_whitespace();
+    // discard #define
+    parts.next();
+
+    let name = match parts.next() {
+        Some(n) => n.into(),
+        None => {
+            return Err(PreprocessorError {
+                line: i,
+                message: "Macros must have a name".into(),
+                source: line.to_string(),
+                file: filename.clone(),
+            })
+        }
+    };
+
+    let value = match parts.next() {
+        Some(v) => v.into(),
+        None => "".into(),
+    };
+
+    Ok((name, value))
+}
+
\ No newline at end of file diff --git a/src/p4/util.rs.html b/src/p4/util.rs.html new file mode 100644 index 00000000..d13304f4 --- /dev/null +++ b/src/p4/util.rs.html @@ -0,0 +1,97 @@ +util.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+
// Copyright 2022 Oxide Computer Company
+
+use crate::ast::{Lvalue, NameInfo, Type, AST};
+use std::collections::HashMap;
+
+pub fn resolve_lvalue(
+    lval: &Lvalue,
+    ast: &AST,
+    names: &HashMap<String, NameInfo>,
+) -> Result<NameInfo, String> {
+    let root = match names.get(lval.root()) {
+        Some(name_info) => name_info,
+        None => return Err(format!("{} not found", lval.root())),
+    };
+    let result = match &root.ty {
+        Type::Bool => root.clone(),
+        Type::Error => root.clone(),
+        Type::Bit(_) => root.clone(),
+        Type::Varbit(_) => root.clone(),
+        Type::Int(_) => root.clone(),
+        Type::String => root.clone(),
+        Type::ExternFunction => root.clone(),
+        Type::HeaderMethod => root.clone(),
+        Type::Table => root.clone(),
+        Type::Void => root.clone(),
+        Type::List(_) => root.clone(),
+        Type::State => root.clone(),
+        Type::Action => root.clone(),
+        Type::UserDefined(name) => {
+            if lval.degree() == 1 {
+                root.clone()
+            } else if let Some(parent) = ast.get_struct(name) {
+                resolve_lvalue(&lval.pop_left(), ast, &parent.names())?
+            } else if let Some(parent) = ast.get_header(name) {
+                resolve_lvalue(&lval.pop_left(), ast, &parent.names())?
+            } else if let Some(parent) = ast.get_extern(name) {
+                resolve_lvalue(&lval.pop_left(), ast, &parent.names())?
+            } else {
+                return Err(format!(
+                    "User defined name '{}' does not exist",
+                    name
+                ));
+            }
+        }
+    };
+    Ok(result)
+}
+
\ No newline at end of file diff --git a/src/p4_macro/lib.rs.html b/src/p4_macro/lib.rs.html new file mode 100644 index 00000000..de1ce31e --- /dev/null +++ b/src/p4_macro/lib.rs.html @@ -0,0 +1,327 @@ +lib.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+
// Copyright 2022 Oxide Computer Company
+
+//! The [`use_p4!`] macro allows for P4 programs to be directly integrated into
+//! Rust programs.
+//!
+//! ```ignore
+//! p4_macro::use_p4!("path/to/p4/program.p4");
+//! ```
+//!
+//! This will generate a `main_pipeline` struct that implements the
+//! [Pipeline](../p4rs/trait.Pipeline.html) trait. The [`use_p4!`] macro expands
+//! directly in to `x4c` compiled code. This includes all data structures,
+//! parsers and control blocks.
+//!
+//! To customize the name of the generated pipeline use the `pipeline_name`
+//! parameter.
+//!
+//! ```ignore
+//! p4_macro::use_p4!(p4 = "path/to/p4/program.p4", pipeline_name = "muffin");
+//! ```
+//! This will result in a `muffin_pipeline` struct being being generated.
+//!
+//! For documentation on using [Pipeline](../p4rs/trait.Pipeline.html) trait, see the
+//! [p4rs](../p4rs/index.html) docs.
+
+use std::fs;
+use std::path::Path;
+use std::sync::Arc;
+
+use p4::check::Diagnostics;
+use p4::{
+    ast::AST, check, error, error::SemanticError, lexer, parser, preprocessor,
+};
+use proc_macro::TokenStream;
+use serde::Deserialize;
+use serde_tokenstream::ParseWrapper;
+use syn::{parse, LitStr};
+
+#[derive(Deserialize)]
+struct MacroSettings {
+    p4: ParseWrapper<LitStr>,
+    pipeline_name: ParseWrapper<LitStr>,
+}
+
+struct GenerationSettings {
+    pipeline_name: String,
+}
+
+impl Default for GenerationSettings {
+    fn default() -> Self {
+        Self {
+            pipeline_name: "main".to_owned(),
+        }
+    }
+}
+
+/// The `use_p4!` macro uses the `x4c` compiler to generate Rust code from a P4
+/// program. The macro itself expands into the generated code. The macro can be
+/// called with only the path to the P4 program as an argument or, it can be
+/// called with the path to the P4 program plus the name to use for the
+/// generated pipeline object.
+///
+/// For usage examples, see the [p4-macro](index.html) module documentation.
+#[proc_macro]
+pub fn use_p4(item: TokenStream) -> TokenStream {
+    match do_use_p4(item) {
+        Err(err) => err.to_compile_error().into(),
+        Ok(out) => out,
+    }
+}
+
+fn do_use_p4(item: TokenStream) -> Result<TokenStream, syn::Error> {
+    let (filename, settings) =
+        if let Ok(filename) = parse::<LitStr>(item.clone()) {
+            (filename.value(), GenerationSettings::default())
+        } else {
+            let MacroSettings { p4, pipeline_name } =
+                serde_tokenstream::from_tokenstream(&item.into())?;
+            (
+                p4.into_inner().value(),
+                GenerationSettings {
+                    pipeline_name: pipeline_name.into_inner().value(),
+                },
+            )
+        };
+
+    generate_rs(filename, settings)
+}
+
+fn generate_rs(
+    filename: String,
+    settings: GenerationSettings,
+) -> Result<TokenStream, syn::Error> {
+    //TODO gracefull error handling
+
+    let mut ast = AST::default();
+    process_file(Arc::new(filename), &mut ast, &settings)?;
+
+    let (hlir, _) = check::all(&ast);
+
+    let tokens: TokenStream = p4_rust::emit_tokens(
+        &ast,
+        &hlir,
+        p4_rust::Settings {
+            pipeline_name: settings.pipeline_name.clone(),
+        },
+    )
+    .into();
+
+    Ok(tokens)
+}
+
+fn process_file(
+    filename: Arc<String>,
+    ast: &mut AST,
+    _settings: &GenerationSettings,
+) -> Result<(), syn::Error> {
+    let contents = match fs::read_to_string(&*filename) {
+        Ok(c) => c,
+        Err(e) => panic!("failed to read file {}: {}", filename, e),
+    };
+    let ppr = preprocessor::run(&contents, filename.clone()).unwrap();
+    for included in &ppr.elements.includes {
+        let path = Path::new(included);
+        if !path.is_absolute() {
+            let parent = Path::new(&*filename).parent().unwrap();
+            let joined = parent.join(included);
+            process_file(
+                Arc::new(joined.to_str().unwrap().to_string()),
+                ast,
+                _settings,
+            )?
+        } else {
+            process_file(Arc::new(included.clone()), ast, _settings)?;
+        }
+    }
+
+    let (_, diags) = check::all(ast);
+    let lines: Vec<&str> = ppr.lines.iter().map(|x| x.as_str()).collect();
+    check(&lines, &diags);
+    let lxr = lexer::Lexer::new(lines.clone(), filename);
+    let mut psr = parser::Parser::new(lxr);
+    psr.run(ast).unwrap();
+    p4_rust::sanitize(ast);
+    Ok(())
+}
+
+// TODO copy pasta from x4c
+fn check(lines: &[&str], diagnostics: &Diagnostics) {
+    let errors = diagnostics.errors();
+    if !errors.is_empty() {
+        let mut err = Vec::new();
+        for e in errors {
+            err.push(SemanticError {
+                at: e.token.clone(),
+                message: e.message.clone(),
+                source: lines[e.token.line].into(),
+            });
+        }
+        panic!("{}", error::Error::Semantic(err));
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_macro_test/main.rs.html b/src/p4_macro_test/main.rs.html new file mode 100644 index 00000000..5d57977d --- /dev/null +++ b/src/p4_macro_test/main.rs.html @@ -0,0 +1,43 @@ +main.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+
// Copyright 2022 Oxide Computer Company
+
+p4_macro::use_p4!("lang/p4-macro-test/src/ether.p4");
+
+fn main() {
+    let buf = [
+        0x11, 0x22, 0x33, 0x44, 0x55, 0x66, // dst mac
+        0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, // src mac
+        0x86, 0xdd, // ipv6 ethertype
+    ];
+
+    let mut eth = ethernet_t::new();
+    eth.set(&buf).unwrap();
+
+    println!("dst: {:x?}", eth.dst_addr.as_raw_slice());
+    println!("src: {:x?}", eth.src_addr.as_raw_slice());
+    let ethertype =
+        u16::from_be_bytes(eth.ether_type.as_raw_slice().try_into().unwrap());
+    println!("ethertype: {:x?}", ethertype);
+}
+
\ No newline at end of file diff --git a/src/p4_rust/control.rs.html b/src/p4_rust/control.rs.html new file mode 100644 index 00000000..7d671b4d --- /dev/null +++ b/src/p4_rust/control.rs.html @@ -0,0 +1,1045 @@ +control.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+
// Copyright 2022 Oxide Computer Company
+
+use crate::{
+    expression::ExpressionGenerator,
+    qualified_table_function_name, rust_type,
+    statement::{StatementContext, StatementGenerator},
+    try_extract_prefix_len, Context,
+};
+use p4::ast::{
+    Action, Control, ControlParameter, Direction, ExpressionKind,
+    KeySetElementValue, MatchKind, Table, Type, AST,
+};
+use p4::hlir::Hlir;
+use p4::util::resolve_lvalue;
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+
+pub(crate) struct ControlGenerator<'a> {
+    ast: &'a AST,
+    ctx: &'a mut Context,
+    hlir: &'a Hlir,
+}
+
+impl<'a> ControlGenerator<'a> {
+    pub(crate) fn new(
+        ast: &'a AST,
+        hlir: &'a Hlir,
+        ctx: &'a mut Context,
+    ) -> Self {
+        Self { ast, hlir, ctx }
+    }
+
+    pub(crate) fn generate(&mut self) {
+        for control in &self.ast.controls {
+            self.generate_control(control);
+        }
+
+        if let Some(ingress) = self.ast.get_control("ingress") {
+            self.generate_top_level_control(ingress);
+        };
+
+        if let Some(egress) = self.ast.get_control("egress") {
+            self.generate_top_level_control(egress);
+        };
+    }
+
+    fn generate_top_level_control(&mut self, control: &Control) {
+        let tables = control.tables(self.ast);
+        for (cs, t) in tables {
+            let qtn = qualified_table_function_name(Some(control), &cs, t);
+            let qtfn = qualified_table_function_name(Some(control), &cs, t);
+            let control = cs.last().unwrap().1;
+            let (_, mut param_types) = self.control_parameters(control);
+            for var in &control.variables {
+                if let Type::UserDefined(typename) = &var.ty {
+                    if self.ast.get_extern(typename).is_some() {
+                        let extern_type = format_ident!("{}", typename);
+                        param_types.push(quote! {
+                            &p4rs::externs::#extern_type
+                        })
+                    }
+                }
+            }
+            let (type_tokens, table_tokens) =
+                self.generate_control_table(control, t, &param_types);
+            let qtn = format_ident!("{}", qtn);
+            let qtfn = format_ident!("{}", qtfn);
+            self.ctx.functions.insert(
+                qtn.to_string(),
+                quote! {
+                    pub fn #qtfn() -> #type_tokens {
+                        #table_tokens
+                    }
+                },
+            );
+        }
+    }
+
+    pub(crate) fn generate_control(
+        &mut self,
+        control: &Control,
+    ) -> (TokenStream, TokenStream) {
+        let (mut params, _param_types) = self.control_parameters(control);
+
+        for action in &control.actions {
+            if action.name == "NoAction" {
+                continue;
+            }
+            self.generate_control_action(control, action);
+        }
+
+        let tables = control.tables(self.ast);
+        for (cs, table) in tables {
+            let c = cs.last().unwrap().1;
+            let qtn = qualified_table_function_name(None, &cs, table);
+            let (_, mut param_types) = self.control_parameters(c);
+            for var in &c.variables {
+                if let Type::UserDefined(typename) = &var.ty {
+                    if self.ast.get_extern(typename).is_some() {
+                        let extern_type = format_ident!("{}", typename);
+                        param_types.push(quote! {
+                            &p4rs::externs::#extern_type
+                        })
+                    }
+                }
+            }
+            let n = table.key.len();
+            let table_type = quote! {
+                p4rs::table::Table::<
+                    #n,
+                    std::sync::Arc<dyn Fn(#(#param_types),*)>
+                    >
+            };
+            let qtn = format_ident!("{}", qtn);
+            params.push(quote! {
+                #qtn: &#table_type
+            });
+        }
+
+        let name = format_ident!("{}_apply", control.name);
+        let apply_body = self.generate_control_apply_body(control);
+        let sig = quote! {
+            (#(#params),*)
+        };
+        self.ctx.functions.insert(
+            name.to_string(),
+            quote! {
+                pub fn #name #sig {
+                    #apply_body
+                }
+            },
+        );
+
+        (sig, apply_body)
+    }
+
+    pub(crate) fn control_parameters(
+        &mut self,
+        control: &Control,
+    ) -> (Vec<TokenStream>, Vec<TokenStream>) {
+        let mut params = Vec::new();
+        let mut types = Vec::new();
+
+        for arg in &control.parameters {
+            match arg.ty {
+                Type::UserDefined(ref typename) => {
+                    match self.ast.get_user_defined_type(typename) {
+                        Some(_udt) => {
+                            let name = format_ident!("{}", arg.name);
+                            let ty = rust_type(&arg.ty);
+                            match &arg.direction {
+                                Direction::Out | Direction::InOut => {
+                                    params.push(quote! {
+                                        #name: &mut #ty
+                                    });
+                                    types.push(quote! { &mut #ty });
+                                }
+                                _ => {
+                                    params.push(quote! {
+                                        #name: &#ty
+                                    });
+                                    types.push(quote! { &#ty });
+                                }
+                            }
+                        }
+                        None => {
+                            // if this is a generic type, skip for now
+                            if control.is_type_parameter(typename) {
+                                continue;
+                            }
+                            panic!("Undefined type {}", typename);
+                        }
+                    }
+                }
+                _ => {
+                    let name = format_ident!("{}", arg.name);
+                    let ty = rust_type(&arg.ty);
+                    match &arg.direction {
+                        Direction::Out | Direction::InOut => {
+                            params.push(quote! { #name: &mut #ty });
+                            types.push(quote! { &mut #ty });
+                        }
+                        _ => {
+                            if arg.ty == Type::Bool {
+                                params.push(quote! { #name: #ty });
+                                types.push(quote! { #ty });
+                            } else {
+                                params.push(quote! { #name: &#ty });
+                                types.push(quote! { &#ty });
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        (params, types)
+    }
+
+    fn generate_control_action(&mut self, control: &Control, action: &Action) {
+        let name = format_ident!("{}_action_{}", control.name, action.name);
+        let (mut params, _) = self.control_parameters(control);
+
+        for var in &control.variables {
+            if let Type::UserDefined(typename) = &var.ty {
+                if self.ast.get_extern(typename).is_some() {
+                    let name = format_ident!("{}", var.name);
+                    let extern_type = format_ident!("{}", typename);
+                    params.push(quote! {
+                        #name: &p4rs::externs::#extern_type
+                    })
+                }
+            }
+        }
+
+        let mut dump_fmt = Vec::new();
+        for p in &action.parameters {
+            dump_fmt.push(p.name.clone() + "={}");
+        }
+        //let dump_fmt = vec!["{}"; action.parameters.len()];
+        let dump_fmt = dump_fmt.join(", ");
+        let dump_args: Vec<TokenStream> = action
+            .parameters
+            .iter()
+            .map(|x| format_ident!("{}", x.name.clone()))
+            .map(|x| quote! { #x })
+            .collect();
+
+        let dump = quote! {
+            // TODO find a way to only allocate the string when probe is active.
+            // Cannot simply return reference to string created within probe.
+            let dump = format!(#dump_fmt, #(#dump_args,)*);
+            softnpu_provider::action!(|| (&dump));
+        };
+
+        for arg in &action.parameters {
+            // if the type is user defined, check to ensure it's defined
+            if let Type::UserDefined(ref typename) = arg.ty {
+                match self.ast.get_user_defined_type(typename) {
+                    Some(_) => {
+                        let name = format_ident!("{}", arg.name);
+                        let ty = rust_type(&arg.ty);
+                        params.push(quote! { #name: #ty });
+                    }
+                    None => {
+                        panic!(
+                            "codegen: undefined type {} for arg {:#?}",
+                            typename, arg,
+                        );
+                    }
+                }
+            } else {
+                let name = format_ident!("{}", arg.name);
+                let ty = rust_type(&arg.ty);
+                params.push(quote! { #name: #ty });
+            }
+        }
+
+        let mut names = control.names();
+        let sg = StatementGenerator::new(
+            self.ast,
+            self.hlir,
+            StatementContext::Control(control),
+        );
+        let body = sg.generate_block(&action.statement_block, &mut names);
+
+        let __name = name.to_string();
+
+        self.ctx.functions.insert(
+            name.to_string(),
+            quote! {
+                pub fn #name(#(#params),*) {
+
+                    //TODO <<<< DTRACE <<<<<<
+                    //Generate dtrace prbes that allow us to trace control
+                    //action flows.
+                    //println!("####{}####", #__name);
+
+                    #dump
+
+                    #body
+                }
+            },
+        );
+    }
+
+    pub(crate) fn generate_control_table(
+        &mut self,
+        control: &Control,
+        table: &Table,
+        control_param_types: &Vec<TokenStream>,
+    ) -> (TokenStream, TokenStream) {
+        let mut key_type_tokens: Vec<TokenStream> = Vec::new();
+        let mut key_types: Vec<Type> = Vec::new();
+
+        for (k, _) in &table.key {
+            let parts: Vec<&str> = k.name.split('.').collect();
+            let root = parts[0];
+
+            // try to find the root of the key as an argument to the control block.
+            // TODO: are there other places to look for this?
+            match Self::get_control_arg(control, root) {
+                Some(_param) => {
+                    if parts.len() > 1 {
+                        let tm = control.names();
+                        //TODO: use hlir?
+                        let ty = resolve_lvalue(k, self.ast, &tm).unwrap().ty;
+                        key_types.push(ty.clone());
+                        key_type_tokens.push(rust_type(&ty));
+                    }
+                }
+                None => {
+                    panic!("bug: control arg undefined {:#?}", root)
+                }
+            }
+        }
+
+        let table_name = format_ident!("{}_table", table.name);
+        let n = table.key.len();
+        let table_type = quote! {
+            p4rs::table::Table::<
+                #n,
+                std::sync::Arc<dyn Fn(#(#control_param_types),*)>
+            >
+        };
+
+        let mut tokens = quote! {
+            let mut #table_name: #table_type = #table_type::new();
+        };
+
+        if table.const_entries.is_empty() {
+            tokens.extend(quote! { #table_name });
+            return (table_type, tokens);
+        }
+
+        for entry in &table.const_entries {
+            let mut keyset = Vec::new();
+            for (i, k) in entry.keyset.iter().enumerate() {
+                match &k.value {
+                    KeySetElementValue::Expression(e) => {
+                        let eg = ExpressionGenerator::new(self.hlir);
+                        let xpr = eg.generate_expression(e.as_ref());
+                        let ks = match table.key[i].1 {
+                            MatchKind::Exact => {
+                                let k = format_ident!("{}", "Exact");
+                                quote! {
+                                    p4rs::table::Key::#k(
+                                        p4rs::bitvec_to_biguint(&#xpr))
+                                }
+                            }
+                            MatchKind::Ternary => {
+                                let k = format_ident!("{}", "Ternary");
+                                quote! {
+                                    p4rs::table::Key::#k(
+                                        p4rs::bitvec_to_biguint(&#xpr))
+                                }
+                            }
+                            MatchKind::LongestPrefixMatch => {
+                                let len = match try_extract_prefix_len(e) {
+                                    Some(len) => len,
+                                    None => {
+                                        panic!(
+                                            "codegen: coult not determine prefix 
+                                        len for key {:#?}",
+                                        table.key[i].1,
+                                        );
+                                    }
+                                };
+                                let k = format_ident!("{}", "Lpm");
+                                quote! {
+                                    p4rs::table::Key::#k(p4rs::table::Prefix{
+                                        addr: bitvec_to_ip6addr(&(#xpr)),
+                                        len: #len,
+                                    })
+                                }
+                            }
+                            MatchKind::Range => {
+                                let k = format_ident!("Range");
+                                quote! {
+                                    p4rs::table::Key::#k(#xpr)
+                                }
+                            }
+                        };
+                        keyset.push(ks);
+                    }
+                    x => todo!("key set element {:?}", x),
+                }
+            }
+
+            let action = match control.get_action(&entry.action.name) {
+                Some(action) => action,
+                None => {
+                    panic!("codegen: action {} not found", entry.action.name);
+                }
+            };
+
+            let mut action_fn_args = Vec::new();
+            for arg in &control.parameters {
+                let a = format_ident!("{}", arg.name);
+                action_fn_args.push(quote! { #a });
+            }
+
+            let action_fn_name =
+                format_ident!("{}_action_{}", control.name, entry.action.name);
+            for (i, expr) in entry.action.parameters.iter().enumerate() {
+                match &expr.kind {
+                    ExpressionKind::IntegerLit(v) => {
+                        match &action.parameters[i].ty {
+                            Type::Bit(n) => {
+                                if *n <= 8 {
+                                    let v = *v as u8;
+                                    action_fn_args.push(quote! {
+                                        #v.view_bits::<Msb0>().to_bitvec()
+                                    });
+                                }
+                            }
+                            x => {
+                                todo!("action int lit expression type {:?}", x)
+                            }
+                        }
+                    }
+                    ExpressionKind::BitLit(width, v) => {
+                        match &action.parameters[i].ty {
+                            Type::Bit(n) => {
+                                let n = *n;
+                                if n != *width as usize {
+                                    panic!(
+                                        "{:?} not compatible with {:?}",
+                                        expr.kind, action.parameters[i],
+                                    );
+                                }
+                                let size = n;
+                                action_fn_args.push(quote! {{
+                                    let mut x = bitvec![mut u8, Msb0; 0; #size];
+                                    x.store_le(#v);
+                                    x
+                                }});
+                            }
+                            x => {
+                                todo!("action bit lit expression type {:?}", x)
+                            }
+                        }
+                    }
+                    x => todo!("action parameter type {:?}", x),
+                }
+            }
+
+            let mut closure_params = Vec::new();
+            for x in &control.parameters {
+                let name = format_ident!("{}", x.name);
+                closure_params.push(quote! { #name });
+            }
+
+            tokens.extend(quote! {
+
+                let action: std::sync::Arc<dyn Fn(#(#control_param_types),*)> =
+                    std::sync::Arc::new(|#(#closure_params),*| {
+                        #action_fn_name(#(#action_fn_args),*);
+                    });
+
+                #table_name.entries.insert(
+                    p4rs::table::TableEntry::<
+                        #n,
+                        std::sync::Arc<dyn Fn(#(#control_param_types),*)>,
+                    >{
+                        key: [#(#keyset),*],
+                        priority: 0,
+                        name: "your name here".into(),
+                        action,
+
+                        //TODO actual data, does this actually matter for
+                        //constant entries?
+                        action_id: String::new(),
+                        parameter_data: Vec::new(),
+                    });
+            })
+        }
+
+        tokens.extend(quote! { #table_name });
+
+        (table_type, tokens)
+    }
+
+    fn generate_control_apply_body(
+        &mut self,
+        control: &Control,
+    ) -> TokenStream {
+        let mut tokens = TokenStream::new();
+
+        for var in &control.variables {
+            //TODO check in checker that externs are actually defined by
+            //SoftNPU.
+            if let Type::UserDefined(typename) = &var.ty {
+                if self.ast.get_extern(typename).is_some() {
+                    let name = format_ident!("{}", var.name);
+                    let extern_type = format_ident!("{}", typename);
+                    tokens.extend(quote! {
+                        let #name = p4rs::externs::#extern_type::new();
+                    })
+                }
+            }
+        }
+
+        let mut names = control.names();
+        let sg = StatementGenerator::new(
+            self.ast,
+            self.hlir,
+            StatementContext::Control(control),
+        );
+        tokens.extend(sg.generate_block(&control.apply, &mut names));
+
+        tokens
+    }
+
+    fn get_control_arg<'b>(
+        control: &'b Control,
+        arg_name: &str,
+    ) -> Option<&'b ControlParameter> {
+        control.parameters.iter().find(|&arg| arg.name == arg_name)
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_rust/expression.rs.html b/src/p4_rust/expression.rs.html new file mode 100644 index 00000000..a45d9c69 --- /dev/null +++ b/src/p4_rust/expression.rs.html @@ -0,0 +1,443 @@ +expression.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+
// Copyright 2022 Oxide Computer Company
+
+use p4::ast::{BinOp, DeclarationInfo, Expression, ExpressionKind, Lvalue};
+use p4::hlir::Hlir;
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+
+pub(crate) struct ExpressionGenerator<'a> {
+    hlir: &'a Hlir,
+}
+
+impl<'a> ExpressionGenerator<'a> {
+    pub fn new(hlir: &'a Hlir) -> Self {
+        Self { hlir }
+    }
+
+    pub(crate) fn generate_expression(&self, xpr: &Expression) -> TokenStream {
+        match &xpr.kind {
+            ExpressionKind::BoolLit(v) => {
+                quote! { #v }
+            }
+            ExpressionKind::IntegerLit(v) => {
+                quote! { #v }
+            }
+            ExpressionKind::BitLit(width, v) => {
+                self.generate_bit_literal(*width, *v)
+            }
+            ExpressionKind::SignedLit(_width, _v) => {
+                todo!("generate expression signed lit");
+            }
+            ExpressionKind::Lvalue(v) => self.generate_lvalue(v),
+            ExpressionKind::Binary(lhs, op, rhs) => {
+                let lhs_tks = self.generate_expression(lhs.as_ref());
+                let op_tks = self.generate_binop(*op);
+                let rhs_tks = self.generate_expression(rhs.as_ref());
+                let mut ts = TokenStream::new();
+                match op {
+                    BinOp::Add => {
+                        ts.extend(quote!{
+                            p4rs::bitmath::add_le(#lhs_tks.clone(), #rhs_tks.clone())
+                        });
+                    }
+                    BinOp::Mod => {
+                        ts.extend(quote!{
+                            p4rs::bitmath::mod_le(#lhs_tks.clone(), #rhs_tks.clone())
+                        });
+                    }
+                    BinOp::Eq | BinOp::NotEq => {
+                        let lhs_tks_ = match &lhs.as_ref().kind {
+                            ExpressionKind::Lvalue(lval) => {
+                                let name_info = self
+                                    .hlir
+                                    .lvalue_decls
+                                    .get(lval)
+                                    .unwrap_or_else(|| {
+                                        panic!(
+                                            "declaration info for {:#?}",
+                                            lval
+                                        )
+                                    });
+                                match name_info.decl {
+                                    DeclarationInfo::ActionParameter(_) => {
+                                        quote! {
+                                            &#lhs_tks
+                                        }
+                                    }
+                                    _ => lhs_tks,
+                                }
+                            }
+                            _ => lhs_tks,
+                        };
+                        let rhs_tks_ = match &rhs.as_ref().kind {
+                            ExpressionKind::Lvalue(lval) => {
+                                let name_info = self
+                                    .hlir
+                                    .lvalue_decls
+                                    .get(lval)
+                                    .unwrap_or_else(|| {
+                                        panic!(
+                                            "declaration info for {:#?}",
+                                            lval
+                                        )
+                                    });
+                                match name_info.decl {
+                                    DeclarationInfo::ActionParameter(_) => {
+                                        quote! {
+                                            &#rhs_tks
+                                        }
+                                    }
+                                    _ => rhs_tks,
+                                }
+                            }
+                            _ => rhs_tks,
+                        };
+                        ts.extend(lhs_tks_);
+                        ts.extend(op_tks);
+                        ts.extend(rhs_tks_);
+                    }
+                    _ => {
+                        ts.extend(lhs_tks);
+                        ts.extend(op_tks);
+                        ts.extend(rhs_tks);
+                    }
+                }
+                ts
+            }
+            ExpressionKind::Index(lval, xpr) => {
+                let mut ts = self.generate_lvalue(lval);
+                ts.extend(self.generate_expression(xpr.as_ref()));
+                ts
+            }
+            ExpressionKind::Slice(begin, end) => {
+                let l = match &begin.kind {
+                    ExpressionKind::IntegerLit(v) => *v as usize,
+                    _ => panic!("slice ranges can only be integer literals"),
+                };
+                let l = l + 1;
+                let r = match &end.kind {
+                    ExpressionKind::IntegerLit(v) => *v as usize,
+                    _ => panic!("slice ranges can only be integer literals"),
+                };
+                quote! {
+                    [#r..#l]
+                }
+            }
+            ExpressionKind::Call(call) => {
+                let lv: Vec<TokenStream> = call
+                    .lval
+                    .name
+                    .split('.')
+                    .map(|x| format_ident!("{}", x))
+                    .map(|x| quote! { #x })
+                    .collect();
+
+                let lvalue = quote! { #(#lv).* };
+                let mut args = Vec::new();
+                for arg in &call.args {
+                    args.push(self.generate_expression(arg));
+                }
+                quote! {
+                    #lvalue(#(#args),*)
+                }
+            }
+            ExpressionKind::List(elements) => {
+                let mut parts = Vec::new();
+                for e in elements {
+                    parts.push(self.generate_expression(e));
+                }
+                quote! {
+                    &[ #(&#parts),* ]
+                }
+            }
+        }
+    }
+
+    pub(crate) fn generate_bit_literal(
+        &self,
+        width: u16,
+        value: u128,
+    ) -> TokenStream {
+        assert!(width <= 128);
+
+        let width = width as usize;
+
+        quote! {
+            {
+                let mut x = bitvec![mut u8, Msb0; 0; #width];
+                x.store_le(#value);
+                x
+            }
+        }
+    }
+
+    pub(crate) fn generate_binop(&self, op: BinOp) -> TokenStream {
+        match op {
+            BinOp::Add => quote! { + },
+            BinOp::Subtract => quote! { - },
+            BinOp::Mod => quote! { % },
+            BinOp::Geq => quote! { >= },
+            BinOp::Gt => quote! { > },
+            BinOp::Leq => quote! { <= },
+            BinOp::Lt => quote! { < },
+            BinOp::Eq => quote! { == },
+            BinOp::NotEq => quote! { != },
+            BinOp::Mask => quote! { & },
+            BinOp::BitAnd => quote! { & },
+            BinOp::BitOr => quote! { | },
+            BinOp::Xor => quote! { ^ },
+        }
+    }
+
+    pub(crate) fn generate_lvalue(&self, lval: &Lvalue) -> TokenStream {
+        let lv: Vec<TokenStream> = lval
+            .name
+            .split('.')
+            .map(|x| format_ident!("{}", x))
+            .map(|x| quote! { #x })
+            .collect();
+
+        let lvalue = quote! { #(#lv).* };
+
+        let name_info = self
+            .hlir
+            .lvalue_decls
+            .get(lval)
+            .unwrap_or_else(|| panic!("declaration info for {:#?}", lval));
+
+        match name_info.decl {
+            DeclarationInfo::HeaderMember => quote! {
+                #lvalue
+            },
+            /*
+            DeclarationInfo::ActionParameter(_) => quote! {
+                &#lvalue
+            },
+            */
+            _ => lvalue,
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_rust/header.rs.html b/src/p4_rust/header.rs.html new file mode 100644 index 00000000..890b7114 --- /dev/null +++ b/src/p4_rust/header.rs.html @@ -0,0 +1,363 @@ +header.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+
// Copyright 2022 Oxide Computer Company
+
+use crate::{rust_type, type_size, Context};
+use p4::ast::{Header, AST};
+use quote::{format_ident, quote};
+
+pub(crate) struct HeaderGenerator<'a> {
+    ast: &'a AST,
+    ctx: &'a mut Context,
+}
+
+impl<'a> HeaderGenerator<'a> {
+    pub(crate) fn new(ast: &'a AST, ctx: &'a mut Context) -> Self {
+        Self { ast, ctx }
+    }
+
+    pub(crate) fn generate(&mut self) {
+        for h in &self.ast.headers {
+            self.generate_header(h);
+        }
+    }
+
+    fn generate_header(&mut self, h: &Header) {
+        let name = format_ident!("{}", h.name);
+
+        //
+        // genrate a rust struct for the header
+        //
+
+        // generate struct members
+        let mut members = Vec::new();
+        for member in &h.members {
+            let name = format_ident!("{}", member.name);
+            let ty = rust_type(&member.ty);
+            members.push(quote! { pub #name: #ty });
+        }
+
+        let mut generated = quote! {
+            #[derive(Debug, Default, Clone)]
+            pub struct #name {
+                pub valid: bool,
+                #(#members),*
+            }
+        };
+
+        //
+        // generate a constructor that maps the header onto a byte slice
+        //
+
+        // generate member assignments
+        let mut member_values = Vec::new();
+        let mut set_statements = Vec::new();
+        let mut to_bitvec_statements = Vec::new();
+        let mut checksum_statements = Vec::new();
+        let mut dump_statements = Vec::new();
+        let fmt = "{} ".repeat(h.members.len() * 2);
+        let fmt = fmt.trim();
+        let mut offset = 0;
+        for member in &h.members {
+            let name = format_ident!("{}", member.name);
+            let name_s = &member.name;
+            let size = type_size(&member.ty, self.ast);
+            member_values.push(quote! {
+                #name: BitVec::<u8, Msb0>::default()
+            });
+            let end = offset + size;
+            set_statements.push(quote! {
+                self.#name = {
+                    let mut b = buf.view_bits::<Msb0>()[#offset..#end].to_owned();
+                    // NOTE this barfing and then unbarfing a vec is to handle
+                    // the p4 confused-endian data model.
+                    let mut v = b.into_vec();
+                    v.reverse();
+                    if ((#end-#offset) % 8) != 0 {
+                        if let Some(x) = v.iter_mut().last() {
+                            *x <<= (#offset % 8);
+                        }
+                    }
+                    let mut b = BitVec::<u8, Msb0>::from_vec(v);
+                    b.resize(#end-#offset, false);
+                    b
+                }
+            });
+            to_bitvec_statements.push(quote! {
+                // NOTE this barfing and then unbarfing a vec is to handle
+                // the p4 confused-endian data model.
+                let mut v = self.#name.clone().into_vec();
+                if ((#end-#offset) % 8) != 0 {
+                    if let Some(x) = v.iter_mut().last() {
+                        *x >>= ((#end - #offset) % 8);
+                    }
+                }
+                v.reverse();
+                let n = (#end-#offset);
+                let m = n%8;
+                let mut b = BitVec::<u8, Msb0>::from_vec(v);
+                x[#offset..#end] |= &b[m..];
+
+            });
+            checksum_statements.push(quote! {
+                csum = p4rs::bitmath::add_le(csum.clone(), self.#name.csum())
+            });
+            dump_statements.push(quote! {
+                #name_s.cyan(),
+                p4rs::dump_bv(&self.#name)
+            });
+
+            offset += size;
+        }
+        let dump = quote! {
+            format!(#fmt, #(#dump_statements),*)
+        };
+
+        //TODO perhaps we should just keep the whole header as one bitvec so we
+        //don't need to construct a consolidated bitvec like to_bitvec does?
+        generated.extend(quote! {
+            impl Header for #name {
+                fn new() -> Self {
+                    Self {
+                        valid: false,
+                        #(#member_values),*
+                    }
+                }
+                fn set(
+                    &mut self,
+                    buf: &[u8]
+                ) -> Result<(), TryFromSliceError> {
+                    #(#set_statements);*;
+                    Ok(())
+                }
+                fn size() -> usize {
+                    #offset
+                }
+                fn set_valid(&mut self) {
+                    self.valid = true;
+                }
+                fn set_invalid(&mut self) {
+                    self.valid = false;
+                }
+                fn is_valid(&self) -> bool {
+                    self.valid
+                }
+                fn to_bitvec(&self) -> BitVec<u8, Msb0> {
+                    let mut x = bitvec![u8, Msb0; 0u8; Self::size()];
+                    #(#to_bitvec_statements);*;
+                    x
+                }
+            }
+
+            impl Checksum for #name {
+                fn csum(&self) -> BitVec::<u8, Msb0> {
+                    let mut csum = BitVec::new();
+                    #(#checksum_statements);*;
+                    csum
+                }
+            }
+
+            impl #name {
+                fn setValid(&mut self) {
+                    self.valid = true;
+                }
+                fn setInvalid(&mut self) {
+                    self.valid = false;
+                }
+                fn isValid(&self) -> bool {
+                    self.valid
+                }
+                fn dump(&self) -> String {
+                    if self.isValid() {
+                        #dump
+                    } else {
+                        "∅".to_owned()
+                    }
+                }
+            }
+        });
+
+        self.ctx.structs.insert(h.name.clone(), generated);
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_rust/lib.rs.html b/src/p4_rust/lib.rs.html new file mode 100644 index 00000000..4b11cf44 --- /dev/null +++ b/src/p4_rust/lib.rs.html @@ -0,0 +1,845 @@ +lib.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+
// Copyright 2022 Oxide Computer Company
+
+use std::collections::HashMap;
+use std::fs;
+use std::io::{self, Write};
+
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+
+use p4::ast::{
+    ActionParameter, Control, ControlParameter, DeclarationInfo, Direction,
+    Expression, ExpressionKind, HeaderMember, Lvalue, MutVisitor, NameInfo,
+    Parser, StructMember, Table, Type, UserDefinedType, AST,
+};
+use p4::hlir::Hlir;
+use p4::util::resolve_lvalue;
+
+use control::ControlGenerator;
+use header::HeaderGenerator;
+use p4struct::StructGenerator;
+use parser::ParserGenerator;
+use pipeline::PipelineGenerator;
+
+mod control;
+mod expression;
+mod header;
+mod p4struct;
+mod parser;
+mod pipeline;
+mod statement;
+
+/// An object for keeping track of state as we generate code.
+#[derive(Default)]
+struct Context {
+    /// Rust structs we've generated.
+    structs: HashMap<String, TokenStream>,
+
+    /// Rust functions we've generated.
+    functions: HashMap<String, TokenStream>,
+
+    /// Pipeline structures we've generated.
+    pipelines: HashMap<String, TokenStream>,
+}
+
+pub struct Settings {
+    /// Name to give to the C-ABI constructor.
+    pub pipeline_name: String,
+}
+
+pub struct Sanitizer {}
+
+impl Sanitizer {
+    pub fn sanitize_string(s: &mut String) {
+        //TODO sanitize other problematic rust tokens
+        if s == "type" {
+            "typ".clone_into(s)
+        }
+        if s == "match" {
+            "match_".clone_into(s)
+        }
+    }
+}
+
+impl MutVisitor for Sanitizer {
+    fn struct_member(&self, m: &mut StructMember) {
+        Self::sanitize_string(&mut m.name);
+    }
+    fn header_member(&self, m: &mut HeaderMember) {
+        Self::sanitize_string(&mut m.name);
+    }
+    fn control_parameter(&self, p: &mut ControlParameter) {
+        Self::sanitize_string(&mut p.name);
+    }
+    fn action_parameter(&self, p: &mut ActionParameter) {
+        Self::sanitize_string(&mut p.name);
+    }
+    fn lvalue(&self, lv: &mut Lvalue) {
+        Self::sanitize_string(&mut lv.name);
+    }
+}
+
+pub fn sanitize(ast: &mut AST) {
+    let s = Sanitizer {};
+    ast.mut_accept(&s);
+}
+
+pub fn emit(
+    ast: &AST,
+    hlir: &Hlir,
+    filename: &str,
+    settings: Settings,
+) -> io::Result<()> {
+    let tokens = emit_tokens(ast, hlir, settings);
+
+    //
+    // format the code and write it out to a Rust source file
+    //
+    let f: syn::File = match syn::parse2(tokens.clone()) {
+        Ok(f) => f,
+        Err(e) => {
+            // On failure write generated code to a tempfile
+            println!("Code generation produced unparsable code");
+            write_to_tempfile(&tokens)?;
+            return Err(io::Error::new(
+                io::ErrorKind::Other,
+                format!("Failed to parse generated code: {:?}", e),
+            ));
+        }
+    };
+    fs::write(filename, prettyplease::unparse(&f))?;
+
+    Ok(())
+}
+
+fn write_to_tempfile(tokens: &TokenStream) -> io::Result<()> {
+    let mut out = tempfile::Builder::new().suffix(".rs").tempfile()?;
+    out.write_all(tokens.to_string().as_bytes())?;
+    println!("Wrote generated code to {}", out.path().display());
+    out.keep()?;
+    Ok(())
+}
+
+pub fn emit_tokens(ast: &AST, hlir: &Hlir, settings: Settings) -> TokenStream {
+    //
+    // initialize a context to track state while we generate code
+    //
+
+    let mut ctx = Context::default();
+
+    //
+    // genearate rust code for the P4 AST
+    //
+
+    let mut hg = HeaderGenerator::new(ast, &mut ctx);
+    hg.generate();
+
+    let mut sg = StructGenerator::new(ast, &mut ctx);
+    sg.generate();
+
+    let mut pg = ParserGenerator::new(ast, hlir, &mut ctx);
+    pg.generate();
+
+    let mut cg = ControlGenerator::new(ast, hlir, &mut ctx);
+    cg.generate();
+
+    let mut pg = PipelineGenerator::new(ast, hlir, &mut ctx, &settings);
+    pg.generate();
+
+    //
+    // collect all the tokens we generated into one stream
+    //
+
+    // start with use statements
+    let mut tokens = quote! {
+        use p4rs::{checksum::Checksum, *};
+        use colored::*;
+        use bitvec::prelude::*;
+    };
+
+    //to lib dtrace probes
+    tokens.extend(dtrace_probes());
+
+    // structs
+    for s in ctx.structs.values() {
+        tokens.extend(s.clone());
+    }
+
+    // functions
+    for s in ctx.functions.values() {
+        tokens.extend(s.clone());
+    }
+
+    // pipelines
+    for p in ctx.pipelines.values() {
+        tokens.extend(p.clone());
+    }
+
+    tokens
+}
+
+fn dtrace_probes() -> TokenStream {
+    quote! {
+        #[usdt::provider]
+        mod softnpu_provider {
+            fn parser_accepted(_: &str) {}
+            fn parser_transition(_: &str) {}
+            fn parser_dropped() {}
+            fn control_apply(_: &str) {}
+            fn control_table_hit(_: &str) {}
+            fn control_table_miss(_: &str) {}
+            fn ingress_dropped(_: &str) {}
+            fn ingress_accepted(_: &str) {}
+            fn egress_dropped(_: &str) {}
+            fn egress_accepted(_: &str) {}
+            fn egress_table_hit(_: &str) {}
+            fn egress_table_miss(_: &str) {}
+            fn action(_: &str) {}
+        }
+    }
+}
+
+#[allow(dead_code)]
+fn get_parser_arg<'a>(
+    parser: &'a Parser,
+    arg_name: &str,
+) -> Option<&'a ControlParameter> {
+    parser.parameters.iter().find(|&arg| arg.name == arg_name)
+}
+
+/// Return the rust type for a given P4 type.
+fn rust_type(ty: &Type) -> TokenStream {
+    match ty {
+        Type::Bool => quote! { bool },
+        Type::Error => todo!("generate error type"),
+        Type::Bit(_size) => {
+            quote! { BitVec::<u8, Msb0> }
+        }
+        Type::Int(_size) => todo!("generate int type"),
+        Type::Varbit(_size) => todo!("generate varbit type"),
+        Type::String => quote! { String },
+        Type::UserDefined(name) => {
+            let typename = format_ident!("{}", name);
+            quote! { #typename }
+        }
+        Type::ExternFunction => {
+            todo!("rust type for extern function");
+        }
+        Type::HeaderMethod => {
+            todo!("rust type for header method");
+        }
+        Type::Table => {
+            todo!("rust type for table");
+        }
+        Type::Void => {
+            quote! { () }
+        }
+        Type::List(_) => todo!("rust type for list"),
+        Type::State => {
+            todo!("rust type for state");
+        }
+        Type::Action => {
+            todo!("rust type for action");
+        }
+    }
+}
+
+fn type_size(ty: &Type, ast: &AST) -> usize {
+    match ty {
+        Type::Bool => 1,
+        Type::Error => todo!("generate error size"),
+        Type::Bit(size) => *size,
+        Type::Int(size) => *size,
+        Type::Varbit(size) => *size,
+        Type::String => todo!("generate string size"),
+        Type::UserDefined(name) => {
+            let mut sz: usize = 0;
+            let udt = ast.get_user_defined_type(name).unwrap_or_else(|| {
+                panic!("expect user defined type: {}", name)
+            });
+
+            match udt {
+                UserDefinedType::Struct(s) => {
+                    for m in &s.members {
+                        sz += type_size(&m.ty, ast);
+                    }
+                    sz
+                }
+                UserDefinedType::Header(h) => {
+                    for m in &h.members {
+                        sz += type_size(&m.ty, ast);
+                    }
+                    sz
+                }
+                UserDefinedType::Extern(_) => {
+                    todo!("size for extern?");
+                }
+            }
+        }
+        Type::ExternFunction => {
+            todo!("type size for extern function");
+        }
+        Type::HeaderMethod => {
+            todo!("type size for header method");
+        }
+        Type::Table => {
+            todo!("type size for table");
+        }
+        Type::Void => 0,
+        Type::List(_) => todo!("type size for list"),
+        Type::State => {
+            todo!("type size for state");
+        }
+        Type::Action => {
+            todo!("type size for action");
+        }
+    }
+}
+
+fn type_size_bytes(ty: &Type, ast: &AST) -> usize {
+    let s = type_size(ty, ast);
+    let mut b = s >> 3;
+    if s % 8 != 0 {
+        b += 1
+    }
+    b
+}
+
+// in the case of an expression
+//
+//   a &&& b
+//
+// where b is an integer literal interpret b as a prefix mask based on the
+// number of leading ones
+fn try_extract_prefix_len(expr: &Expression) -> Option<u8> {
+    match &expr.kind {
+        ExpressionKind::Binary(_lhs, _op, rhs) => match &rhs.kind {
+            ExpressionKind::IntegerLit(v) => Some(v.leading_ones() as u8),
+            ExpressionKind::BitLit(_width, v) => Some(v.leading_ones() as u8),
+            ExpressionKind::SignedLit(_width, v) => {
+                Some(v.trailing_ones() as u8)
+            }
+            _ => None,
+        },
+        _ => None,
+    }
+}
+
+fn is_header(
+    lval: &Lvalue,
+    ast: &AST,
+    names: &HashMap<String, NameInfo>,
+) -> bool {
+    //TODO: get from hlir?
+    let typename = match resolve_lvalue(lval, ast, names).unwrap().ty {
+        Type::UserDefined(name) => name,
+        _ => return false,
+    };
+    ast.get_header(&typename).is_some()
+}
+
+fn is_header_member(lval: &Lvalue, hlir: &Hlir) -> bool {
+    if lval.degree() >= 1 {
+        let name_info = hlir
+            .lvalue_decls
+            .get(lval)
+            .unwrap_or_else(|| panic!("name for lval {:#?}", lval));
+
+        matches!(name_info.decl, DeclarationInfo::HeaderMember)
+    } else {
+        false
+    }
+}
+
+// TODO define in terms of hlir rather than names
+fn is_rust_reference(lval: &Lvalue, names: &HashMap<String, NameInfo>) -> bool {
+    if lval.degree() == 1 {
+        let name_info = names
+            .get(lval.root())
+            .unwrap_or_else(|| panic!("name for lval {:#?}", lval));
+
+        match name_info.decl {
+            DeclarationInfo::Parameter(Direction::Unspecified) => false,
+            DeclarationInfo::Parameter(Direction::In) => false,
+            DeclarationInfo::Parameter(Direction::Out) => true,
+            DeclarationInfo::Parameter(Direction::InOut) => true,
+            DeclarationInfo::Local => false,
+            DeclarationInfo::Method => false,
+            DeclarationInfo::StructMember => false,
+            DeclarationInfo::HeaderMember => false,
+            DeclarationInfo::ControlTable => false,
+            DeclarationInfo::ControlMember => false,
+            DeclarationInfo::State => false,
+            DeclarationInfo::Action => false,
+            DeclarationInfo::ActionParameter(_) => false,
+        }
+    } else {
+        false
+    }
+}
+
+fn qualified_table_name(
+    control: Option<&Control>,
+    chain: &Vec<(String, &Control)>,
+    table: &Table,
+) -> String {
+    match control {
+        Some(control) => {
+            format!("{}.{}", control.name, table_qname(chain, table, '.'))
+        }
+        _ => table_qname(chain, table, '.'),
+    }
+}
+
+fn qualified_table_function_name(
+    control: Option<&Control>,
+    chain: &Vec<(String, &Control)>,
+    table: &Table,
+) -> String {
+    match control {
+        Some(control) => {
+            format!("{}_{}", control.name, table_qname(chain, table, '_'))
+        }
+        _ => table_qname(chain, table, '_'),
+    }
+}
+
+fn table_qname(
+    chain: &Vec<(String, &Control)>,
+    table: &Table,
+    sep: char,
+) -> String {
+    let mut qname = String::new();
+    for c in chain {
+        if c.0.is_empty() {
+            continue;
+        }
+        qname += &format!("{}{}", c.0, sep);
+    }
+    qname += &table.name;
+    qname
+}
+
\ No newline at end of file diff --git a/src/p4_rust/p4struct.rs.html b/src/p4_rust/p4struct.rs.html new file mode 100644 index 00000000..b707a3a4 --- /dev/null +++ b/src/p4_rust/p4struct.rs.html @@ -0,0 +1,297 @@ +p4struct.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+
// Copyright 2022 Oxide Computer Company
+
+use crate::Context;
+use p4::ast::{Struct, Type, AST};
+use quote::{format_ident, quote};
+
+pub(crate) struct StructGenerator<'a> {
+    ast: &'a AST,
+    ctx: &'a mut Context,
+}
+
+impl<'a> StructGenerator<'a> {
+    pub(crate) fn new(ast: &'a AST, ctx: &'a mut Context) -> Self {
+        Self { ast, ctx }
+    }
+
+    pub(crate) fn generate(&mut self) {
+        for s in &self.ast.structs {
+            self.generate_struct(s);
+        }
+    }
+
+    fn generate_struct(&mut self, s: &Struct) {
+        let mut members = Vec::new();
+        let mut valid_member_size = Vec::new();
+        let mut to_bitvec_stmts = Vec::new();
+        let mut dump_statements = Vec::new();
+        let fmt = "{}: {}\n".repeat(s.members.len());
+        let fmt = fmt.trim();
+
+        for member in &s.members {
+            let name = format_ident!("{}", member.name);
+            let name_s = &member.name;
+            match &member.ty {
+                Type::UserDefined(ref typename) => {
+                    if self.ast.get_header(typename).is_some() {
+                        let ty = format_ident!("{}", typename);
+
+                        // member generation
+                        members.push(quote! { pub #name: #ty });
+
+                        // valid header size statements
+                        valid_member_size.push(quote! {
+                            if self.#name.valid {
+                                x += #ty::size();
+                            }
+                        });
+
+                        // to bitvec statements
+                        to_bitvec_stmts.push(quote!{
+                            if self.#name.valid {
+                                x[off..off+#ty::size()] |= self.#name.to_bitvec();
+                                off += #ty::size();
+                            }
+                        });
+
+                        dump_statements.push(quote! {
+                            #name_s.blue(),
+                            self.#name.dump()
+                        });
+                    } else {
+                        panic!(
+                            "Struct member {:#?} undefined in {:#?}",
+                            member, s
+                        );
+                    }
+                }
+                Type::Bit(size) => {
+                    members.push(quote! { pub #name: BitVec::<u8, Msb0> });
+                    dump_statements.push(quote! {
+                        #name_s.blue(),
+                        p4rs::dump_bv(&self.#name)
+                    });
+                    valid_member_size.push(quote! {
+                            x += #size;
+                    });
+                    to_bitvec_stmts.push(quote! {
+                        x[off..off+#size] |= self.#name.to_bitvec();
+                        off += #size;
+                    });
+                }
+                Type::Bool => {
+                    members.push(quote! { pub #name: bool });
+                    dump_statements.push(quote! {
+                        #name_s.blue(),
+                        self.#name
+                    });
+                }
+                x => {
+                    todo!("struct member {}", x)
+                }
+            }
+        }
+
+        let dump = quote! {
+            format!(#fmt, #(#dump_statements),*)
+        };
+
+        let name = format_ident!("{}", s.name);
+
+        let mut structure = quote! {
+            #[derive(Debug, Default, Clone)]
+            pub struct #name {
+                #(#members),*
+            }
+        };
+        if !valid_member_size.is_empty() {
+            structure.extend(quote! {
+                impl #name {
+                    fn valid_header_size(&self) -> usize {
+                        let mut x: usize = 0;
+                        #(#valid_member_size)*
+                        x
+                    }
+
+                    fn to_bitvec(&self) -> BitVec<u8, Msb0> {
+                        let mut x =
+                            bitvec![u8, Msb0; 0; self.valid_header_size()];
+                        let mut off = 0;
+                        #(#to_bitvec_stmts)*
+                        x
+                    }
+
+                    fn dump(&self) -> String {
+                        #dump
+                    }
+                }
+            })
+        } else {
+            structure.extend(quote! {
+                impl #name {
+                    fn valid_header_size(&self) -> usize { 0 }
+
+                    fn to_bitvec(&self) -> BitVec<u8, Msb0> {
+                        bitvec![u8, Msb0; 0; 0]
+                    }
+
+                    fn dump(&self) -> String {
+                        std::string::String::new()
+                    }
+                }
+            })
+        }
+
+        self.ctx.structs.insert(s.name.clone(), structure);
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_rust/parser.rs.html b/src/p4_rust/parser.rs.html new file mode 100644 index 00000000..22d03d3a --- /dev/null +++ b/src/p4_rust/parser.rs.html @@ -0,0 +1,177 @@ +parser.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+
// Copyright 2022 Oxide Computer Company
+
+use crate::{
+    rust_type,
+    statement::{StatementContext, StatementGenerator},
+    Context,
+};
+use p4::ast::{Direction, Parser, State, AST};
+use p4::hlir::Hlir;
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+
+pub(crate) struct ParserGenerator<'a> {
+    ast: &'a AST,
+    ctx: &'a mut Context,
+    hlir: &'a Hlir,
+}
+
+impl<'a> ParserGenerator<'a> {
+    pub(crate) fn new(
+        ast: &'a AST,
+        hlir: &'a Hlir,
+        ctx: &'a mut Context,
+    ) -> Self {
+        Self { ast, hlir, ctx }
+    }
+
+    pub(crate) fn generate(&mut self) {
+        for parser in &self.ast.parsers {
+            for state in &parser.states {
+                self.generate_state_function(parser, state);
+            }
+        }
+    }
+
+    pub(crate) fn generate_state_function(
+        &mut self,
+        parser: &Parser,
+        state: &State,
+    ) -> (TokenStream, TokenStream) {
+        let function_name = format_ident!("{}_{}", parser.name, state.name);
+
+        let mut args = Vec::new();
+        for arg in &parser.parameters {
+            let name = format_ident!("{}", arg.name);
+            let typename = rust_type(&arg.ty);
+            match arg.direction {
+                Direction::Out | Direction::InOut => {
+                    args.push(quote! { #name: &mut #typename });
+                }
+                _ => args.push(quote! { #name: &mut #typename }),
+            };
+        }
+
+        let body = self.generate_state_function_body(parser, state);
+
+        let signature = quote! {
+            (#(#args),*) -> bool
+        };
+
+        let function = quote! {
+            pub fn #function_name #signature {
+                #body
+            }
+        };
+
+        self.ctx
+            .functions
+            .insert(function_name.to_string(), function);
+
+        (signature, body)
+    }
+
+    fn generate_state_function_body(
+        &mut self,
+        parser: &Parser,
+        state: &State,
+    ) -> TokenStream {
+        let sg = StatementGenerator::new(
+            self.ast,
+            self.hlir,
+            StatementContext::Parser(parser),
+        );
+        let mut names = parser.names();
+        sg.generate_block(&state.statements, &mut names)
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_rust/pipeline.rs.html b/src/p4_rust/pipeline.rs.html new file mode 100644 index 00000000..6357267a --- /dev/null +++ b/src/p4_rust/pipeline.rs.html @@ -0,0 +1,2193 @@ +pipeline.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+
// Copyright 2022 Oxide Computer Company
+
+use crate::{
+    qualified_table_function_name, qualified_table_name, rust_type,
+    type_size_bytes, Context, Settings,
+};
+use p4::ast::{
+    Control, Direction, MatchKind, PackageInstance, Parser, Table, Type, AST,
+};
+use p4::hlir::Hlir;
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+
+pub(crate) struct PipelineGenerator<'a> {
+    ast: &'a AST,
+    ctx: &'a mut Context,
+    hlir: &'a Hlir,
+    settings: &'a Settings,
+}
+
+impl<'a> PipelineGenerator<'a> {
+    pub(crate) fn new(
+        ast: &'a AST,
+        hlir: &'a Hlir,
+        ctx: &'a mut Context,
+        settings: &'a Settings,
+    ) -> Self {
+        Self {
+            ast,
+            hlir,
+            ctx,
+            settings,
+        }
+    }
+
+    pub(crate) fn generate(&mut self) {
+        if let Some(ref inst) = self.ast.package_instance {
+            self.generate_pipeline(inst);
+        }
+    }
+
+    pub(crate) fn generate_pipeline(&mut self, inst: &PackageInstance) {
+        //TODO check instance against package definition instead of hardcoding
+        //SoftNPU in below. This begs the question, will the Rust back end
+        //support something besides SoftNPU. Probably not for the forseeable
+        //future. However it could be interesting to support different package
+        //structures to emulate different types of hardware. For example the
+        //Tofino package instance has a relatively complex pipeline structure.
+        //And it could be interesting/useful to evaluate workloads running
+        //within SoftNPU that exploit that structure.
+
+        if inst.instance_type != "SoftNPU" {
+            //TODO check this in the checker for a nicer failure mode.
+            panic!("Only the SoftNPU package is supported");
+        }
+
+        if inst.parameters.len() != 3 {
+            //TODO check this in the checker for a nicer failure mode.
+            panic!("SoftNPU instances take exactly 3 parameters");
+        }
+
+        let parser = match self.ast.get_parser(&inst.parameters[0]) {
+            Some(p) => p,
+            None => {
+                //TODO check this in the checker for a nicer failure mode.
+                panic!("First argument to SoftNPU must be a parser");
+            }
+        };
+
+        let ingress = match self.ast.get_control(&inst.parameters[1]) {
+            Some(c) => c,
+            None => {
+                //TODO check this in the checker for a nicer failure mode.
+                panic!("Second argument to SoftNPU must be a control block");
+            }
+        };
+
+        let egress = match self.ast.get_control(&inst.parameters[2]) {
+            Some(c) => c,
+            None => {
+                //TODO check this in the checker for a nicer failure mode.
+                panic!("Third argument to SoftNPU must be a control block");
+            }
+        };
+
+        let pipeline_name = format_ident!("{}_pipeline", inst.name);
+
+        //
+        // get table members and initializers from both the ingress and egress
+        // controllers.
+        //
+
+        let (mut table_members, mut table_initializers) =
+            self.table_members(ingress);
+
+        let (egress_table_members, egress_table_initializers) =
+            self.table_members(egress);
+
+        table_members.extend_from_slice(&egress_table_members);
+        table_initializers.extend_from_slice(&egress_table_initializers);
+
+        //
+        // parser, ingress and egress function members
+        //
+
+        let (parse_member, parser_initializer) = self.parse_entrypoint(parser);
+
+        let (ingress_member, ingress_initializer) =
+            self.control_entrypoint("ingress", ingress);
+
+        let (egress_member, egress_initializer) =
+            self.control_entrypoint("egress", egress);
+
+        let (pipeline_impl_process_packet, process_packet_headers) =
+            self.pipeline_impl_process_packet(parser, ingress, egress);
+
+        let add_table_entry_method =
+            self.add_table_entry_method(ingress, egress);
+        let remove_table_entry_method =
+            self.remove_table_entry_method(ingress, egress);
+        let get_table_entries_method =
+            self.get_table_entries_method(ingress, egress);
+        let get_table_ids_method = self.get_table_ids_method(ingress, egress);
+
+        let table_modifiers = self.table_modifiers(ingress, egress);
+
+        let c_create_fn =
+            format_ident!("_{}_pipeline_create", self.settings.pipeline_name);
+
+        let pipeline = quote! {
+            pub struct #pipeline_name {
+                #(#table_members,)*
+                #parse_member,
+                #ingress_member,
+                #egress_member,
+                radix: u16,
+            }
+
+            impl #pipeline_name {
+                pub fn new(radix: u16) -> Self {
+                    usdt::register_probes().unwrap();
+                    Self {
+                        #(#table_initializers,)*
+                        #parser_initializer,
+                        #ingress_initializer,
+                        #egress_initializer,
+                        radix,
+                    }
+                }
+                #process_packet_headers
+                #table_modifiers
+            }
+
+            impl p4rs::Pipeline for #pipeline_name {
+                #pipeline_impl_process_packet
+                #add_table_entry_method
+                #remove_table_entry_method
+                #get_table_entries_method
+                #get_table_ids_method
+            }
+
+            unsafe impl Send for #pipeline_name { }
+
+            #[no_mangle]
+            pub extern "C" fn #c_create_fn(radix: u16)
+            -> *mut dyn p4rs::Pipeline{
+                let pipeline = main_pipeline::new(radix);
+                let boxpipe: Box<dyn p4rs::Pipeline> = Box::new(pipeline);
+                Box::into_raw(boxpipe)
+            }
+        };
+
+        self.ctx.pipelines.insert(inst.name.clone(), pipeline);
+    }
+
+    fn pipeline_impl_process_packet(
+        &mut self,
+        parser: &Parser,
+        ingress: &Control,
+        egress: &Control,
+    ) -> (TokenStream, TokenStream) {
+        let parsed_type = rust_type(&parser.parameters[1].ty);
+        // determine table arguments
+        let ingress_tables = ingress.tables(self.ast);
+        //TODO(dry)
+        let mut ingress_tbl_args = Vec::new();
+        for (cs, t) in ingress_tables {
+            let qtfn = qualified_table_function_name(Some(ingress), &cs, t);
+            let name = format_ident!("{}", qtfn);
+            ingress_tbl_args.push(quote! {
+                &self.#name
+            });
+        }
+        let egress_tables = egress.tables(self.ast);
+        let mut egress_tbl_args = Vec::new();
+        for (cs, t) in egress_tables {
+            let qtfn = qualified_table_function_name(Some(egress), &cs, t);
+            let name = format_ident!("{}", qtfn);
+            egress_tbl_args.push(quote! {
+                &self.#name
+            });
+        }
+
+        let process_packet = quote! {
+            fn process_packet<'a>(
+                &mut self,
+                port: u16,
+                pkt: &mut packet_in<'a>,
+            ) -> Vec<(packet_out<'a>, u16)> {
+                //
+                // Instantiate the parser out type
+                //
+
+                let mut parsed = #parsed_type::default();
+
+                //
+                // Instantiate ingress/egress metadata
+                //
+
+                let mut ingress_metadata = ingress_metadata_t{
+                    port: {
+                        let mut x = bitvec![mut u8, Msb0; 0; 16];
+                        x.store_le(port);
+                        x
+                    },
+                    ..Default::default()
+                };
+                let mut egress_metadata = egress_metadata_t::default();
+
+                //
+                // Run the parser block
+                //
+
+                let accept = (self.parse)(pkt, &mut parsed, &mut ingress_metadata);
+                if !accept {
+                    // drop the packet
+                    softnpu_provider::parser_dropped!(||());
+                    return Vec::new();
+                }
+                let dump = format!("\n{}", parsed.dump());
+                softnpu_provider::parser_accepted!(||(&dump));
+
+                //
+                // Calculate parsed header size
+                //
+
+                let parsed_size = parsed.valid_header_size() >> 3;
+
+                //
+                // Run the ingress block
+                //
+
+                (self.ingress)(
+                    &mut parsed,
+                    &mut ingress_metadata,
+                    &mut egress_metadata,
+                    #(#ingress_tbl_args),*
+                );
+
+                //
+                // Determine egress ports
+                //
+
+                let ports = if egress_metadata.broadcast {
+                    let mut ports = Vec::new();
+                    for p in 0..self.radix {
+                        if p == port {
+                            continue;
+                        }
+                        ports.push(p);
+                    }
+                    ports
+                } else {
+                    if egress_metadata.port.is_empty() || egress_metadata.drop {
+                        Vec::new()
+                    } else {
+                        vec![egress_metadata.port.load_le()]
+                    }
+                };
+
+                let dump = parsed.dump();
+
+                if ports.is_empty() {
+                    softnpu_provider::ingress_dropped!(||(&dump));
+                    return Vec::new();
+                }
+
+                let dump = format!("\n{}", parsed.dump());
+                softnpu_provider::ingress_accepted!(||(&dump));
+
+                //
+                // Run output of ingress block through egress block on each
+                // egress port.
+                //
+                let mut result = Vec::new();
+                for eport in ports {
+
+                    let mut egm = egress_metadata.clone();
+                    let mut parsed_ = parsed.clone();
+
+                    //
+                    // Run the egress block
+                    //
+
+                    egm.port = {
+                        let mut x = bitvec![mut u8, Msb0; 0; 16];
+                        x.store_le(eport);
+                        x
+                    };
+
+                    (self.egress)(
+                        &mut parsed_,
+                        &mut ingress_metadata,
+                        &mut egm,
+                        #(#egress_tbl_args),*
+                    );
+
+                    if egm.drop {
+                        continue;
+                    }
+
+                    //
+                    // Create the packet output.
+                    //
+
+                    let bv = parsed_.to_bitvec();
+                    let buf = bv.as_raw_slice();
+                    let out = packet_out{
+                        header_data: buf.to_owned(),
+                        payload_data: &pkt.data[parsed_size..],
+                    };
+                    result.push((out, eport))
+
+                }
+                result
+            }
+        };
+
+        //TODO factor out commonalities with process_packet
+        let process_packet_headers = quote! {
+            fn process_packet_headers<'a>(
+                &mut self,
+                port: u16,
+                pkt: &mut packet_in<'a>,
+            ) -> Vec<(#parsed_type, u16)> {
+                //
+                // Instantiate the parser out type
+                //
+
+                let mut parsed = #parsed_type::default();
+
+                //
+                // Instantiate ingress/egress metadata
+                //
+
+                let mut ingress_metadata = ingress_metadata_t{
+                    port: {
+                        let mut x = bitvec![mut u8, Msb0; 0; 16];
+                        x.store_le(port);
+                        x
+                    },
+                    ..Default::default()
+                };
+                let mut egress_metadata = egress_metadata_t::default();
+
+                //
+                // Run the parser block
+                //
+
+                let accept = (self.parse)(pkt, &mut parsed, &mut ingress_metadata);
+                if !accept {
+                    // drop the packet
+                    softnpu_provider::parser_dropped!(||());
+                    return Vec::new();
+                }
+                let dump = format!("\n{}", parsed.dump());
+                softnpu_provider::parser_accepted!(||(&dump));
+
+                //
+                // Calculate parsed header size
+                //
+
+                let parsed_size = parsed.valid_header_size() >> 3;
+
+                //
+                // Run the ingress block
+                //
+
+                (self.ingress)(
+                    &mut parsed,
+                    &mut ingress_metadata,
+                    &mut egress_metadata,
+                    #(#ingress_tbl_args),*
+                );
+
+                //
+                // Determine egress ports
+                //
+
+                let ports = if egress_metadata.broadcast {
+                    let mut ports = Vec::new();
+                    for p in 0..self.radix {
+                        if p == port {
+                            continue;
+                        }
+                        ports.push(p);
+                    }
+                    ports
+                } else {
+                    if egress_metadata.port.is_empty() || egress_metadata.drop {
+                        Vec::new()
+                    } else {
+                        vec![egress_metadata.port.load_le()]
+                    }
+                };
+
+                let dump = parsed.dump();
+
+                if ports.is_empty() {
+                    softnpu_provider::ingress_dropped!(||(&dump));
+                    return Vec::new();
+                }
+
+                let dump = format!("\n{}", parsed.dump());
+                softnpu_provider::ingress_accepted!(||(&dump));
+
+                //
+                // Run output of ingress block through egress block on each
+                // egress port.
+                //
+                let mut result = Vec::new();
+                for eport in ports {
+
+                    let mut egm = egress_metadata.clone();
+                    let mut parsed_ = parsed.clone();
+
+                    //
+                    // Run the egress block
+                    //
+
+                    egm.port = {
+                        let mut x = bitvec![mut u8, Msb0; 0; 16];
+                        x.store_le(eport);
+                        x
+                    };
+
+                    (self.egress)(
+                        &mut parsed_,
+                        &mut ingress_metadata,
+                        &mut egm,
+                        #(#egress_tbl_args),*
+                    );
+
+                    if egm.drop {
+                        continue;
+                    }
+
+                    //
+                    // Create the packet output.
+                    //
+
+                    result.push((parsed_, eport))
+
+                }
+                result
+            }
+        };
+
+        (process_packet, process_packet_headers)
+    }
+
+    pub(crate) fn table_members(
+        &mut self,
+        control: &Control,
+    ) -> (Vec<TokenStream>, Vec<TokenStream>) {
+        let mut members = Vec::new();
+        let mut initializers = Vec::new();
+        let mut cg =
+            crate::ControlGenerator::new(self.ast, self.hlir, self.ctx);
+
+        let tables = control.tables(self.ast);
+        for (cs, table) in tables {
+            let table_control = cs.last().unwrap().1;
+            let qtn = qualified_table_function_name(Some(control), &cs, table);
+            let fqtn = qualified_table_function_name(Some(control), &cs, table);
+            let (_, mut param_types) = cg.control_parameters(table_control);
+
+            for var in &table_control.variables {
+                if let Type::UserDefined(typename) = &var.ty {
+                    if self.ast.get_extern(typename).is_some() {
+                        let extern_type = format_ident!("{}", typename);
+                        param_types.push(quote! {
+                            &p4rs::externs::#extern_type
+                        })
+                    }
+                }
+            }
+
+            let n = table.key.len();
+            let table_type = quote! {
+                p4rs::table::Table::<
+                    #n,
+                    std::sync::Arc<dyn Fn(#(#param_types),*)>
+                    >
+            };
+            let qtn = format_ident!("{}", qtn);
+            let fqtn = format_ident!("{}", fqtn);
+            members.push(quote! {
+                pub #qtn: #table_type
+            });
+            initializers.push(quote! {
+                #qtn: #fqtn()
+            })
+        }
+
+        (members, initializers)
+    }
+
+    fn add_table_entry_method(
+        &mut self,
+        ingress: &Control,
+        egress: &Control,
+    ) -> TokenStream {
+        let mut body = TokenStream::new();
+
+        for control in &[ingress, egress] {
+            let tables = control.tables(self.ast);
+            for (cs, table) in tables.iter() {
+                let qtn = qualified_table_name(Some(control), cs, table);
+                let qtfn =
+                    qualified_table_function_name(Some(control), cs, table);
+                let call = format_ident!("add_{}_entry", qtfn);
+                body.extend(quote! {
+                    #qtn => self.#call(
+                        action_id,
+                        keyset_data,
+                        parameter_data,
+                        priority,
+                    ),
+                });
+            }
+        }
+
+        body.extend(quote! {
+            x => println!("add table entry: unknown table id {}, ignoring", x),
+        });
+
+        quote! {
+            fn add_table_entry(
+                &mut self,
+                table_id: &str,
+                action_id: &str,
+                keyset_data: &[u8],
+                parameter_data: &[u8],
+                priority: u32,
+            ) {
+                match table_id {
+                    #body
+                }
+            }
+        }
+    }
+
+    fn remove_table_entry_method(
+        &mut self,
+        ingress: &Control,
+        egress: &Control,
+    ) -> TokenStream {
+        let mut body = TokenStream::new();
+
+        for control in &[ingress, egress] {
+            let tables = control.tables(self.ast);
+            for (cs, table) in tables.iter() {
+                let qtn = qualified_table_name(Some(control), cs, table);
+                let qftn =
+                    qualified_table_function_name(Some(control), cs, table);
+                let call = format_ident!("remove_{}_entry", qftn);
+                body.extend(quote! {
+                    #qtn => self.#call(keyset_data),
+                });
+            }
+        }
+
+        body.extend(quote!{
+            x => println!("remove table entry: unknown table id {}, ignoring", x),
+        });
+
+        quote! {
+            fn remove_table_entry(
+                &mut self,
+                table_id: &str,
+                keyset_data: &[u8],
+            ) {
+                match table_id {
+                    #body
+                }
+            }
+        }
+    }
+
+    fn get_table_ids_method(
+        &mut self,
+        ingress: &Control,
+        egress: &Control,
+    ) -> TokenStream {
+        let mut names = Vec::new();
+
+        for control in &[ingress, egress] {
+            let tables = control.tables(self.ast);
+            for (cs, table) in &tables {
+                names.push(qualified_table_name(Some(control), cs, table));
+            }
+        }
+        quote! {
+            fn get_table_ids(&self) -> Vec<&str> {
+                vec![#(#names),*]
+            }
+        }
+    }
+
+    fn get_table_entries_method(
+        &mut self,
+        ingress: &Control,
+        egress: &Control,
+    ) -> TokenStream {
+        let mut body = TokenStream::new();
+
+        for control in &[ingress, egress] {
+            let tables = control.tables(self.ast);
+            for (cs, table) in tables.iter() {
+                let qtn = qualified_table_name(Some(control), cs, table);
+                let qtfn =
+                    qualified_table_function_name(Some(control), cs, table);
+                let call = format_ident!("get_{}_entries", qtfn);
+                body.extend(quote! {
+                    #qtn => Some(self.#call()),
+                });
+            }
+        }
+
+        body.extend(quote! {
+            x => None,
+        });
+
+        quote! {
+            fn get_table_entries(
+                &self,
+                table_id: &str,
+            ) -> Option<Vec<p4rs::TableEntry>> {
+                match table_id {
+                    #body
+                }
+            }
+        }
+    }
+
+    fn table_modifiers(
+        &mut self,
+        ingress: &Control,
+        egress: &Control,
+    ) -> TokenStream {
+        let mut tokens = TokenStream::new();
+        self.table_modifiers_for_control(&mut tokens, ingress);
+        self.table_modifiers_for_control(&mut tokens, egress);
+        tokens
+    }
+
+    fn table_modifiers_for_control(
+        &mut self,
+        tokens: &mut TokenStream,
+        control: &Control,
+    ) {
+        let tables = control.tables(self.ast);
+        for (cs, table) in tables {
+            let table_control = cs.last().unwrap().1;
+            let qtfn = qualified_table_function_name(Some(control), &cs, table);
+            tokens.extend(self.add_table_entry_function(
+                table,
+                table_control,
+                &qtfn,
+            ));
+            tokens.extend(self.remove_table_entry_function(
+                table,
+                table_control,
+                &qtfn,
+            ));
+            tokens.extend(self.get_table_entries_function(
+                table,
+                table_control,
+                &qtfn,
+            ));
+        }
+    }
+
+    fn table_entry_keys(&mut self, table: &Table) -> Vec<TokenStream> {
+        let mut keys = Vec::new();
+        let mut offset: usize = 0;
+        for (lval, match_kind) in &table.key {
+            let name_info =
+                self.hlir.lvalue_decls.get(lval).unwrap_or_else(|| {
+                    panic!("declaration info for {:#?}", lval,)
+                });
+            let sz = type_size_bytes(&name_info.ty, self.ast);
+            match match_kind {
+                MatchKind::Exact => keys.push(quote! {
+                    p4rs::extract_exact_key(
+                        keyset_data,
+                        #offset,
+                        #sz,
+                    )
+                }),
+                MatchKind::Ternary => {
+                    keys.push(quote! {
+                        p4rs::extract_ternary_key(
+                            keyset_data,
+                            #offset,
+                            #sz,
+                        )
+                    });
+                    offset += 1; // for care/dontcare indicator
+                }
+                MatchKind::LongestPrefixMatch => keys.push(quote! {
+                    p4rs::extract_lpm_key(
+                        keyset_data,
+                        #offset,
+                        #sz,
+                    )
+                }),
+                MatchKind::Range => keys.push(quote! {
+                    p4rs::extract_range_key(
+                        keyset_data,
+                        #offset,
+                        #sz,
+                    )
+                }),
+            }
+            offset += sz;
+        }
+
+        keys
+    }
+
+    fn add_table_entry_function(
+        &mut self,
+        table: &Table,
+        control: &Control,
+        qtfn: &str,
+    ) -> TokenStream {
+        let keys = self.table_entry_keys(table);
+
+        let mut action_match_body = TokenStream::new();
+        for action in table.actions.iter() {
+            let call =
+                format_ident!("{}_action_{}", control.name, &action.name);
+            let n = table.key.len();
+            //XXX hack
+            if &action.name == "NoAction" {
+                continue;
+            }
+            let a = control.get_action(&action.name).unwrap_or_else(|| {
+                panic!(
+                    "control {} must have action {}",
+                    control.name, &action.name,
+                )
+            });
+            let mut parameter_tokens = Vec::new();
+            let mut parameter_refs = Vec::new();
+            let mut offset: usize = 0;
+            for p in &a.parameters {
+                let pname = format_ident!("{}", p.name);
+                match &p.ty {
+                    Type::Bool => {
+                        parameter_tokens.push(quote! {
+                            let #pname = p4rs::extract_bool_action_parameter(
+                                parameter_data,
+                                #offset,
+                            );
+                        });
+                        offset += 1;
+                    }
+                    Type::Error => {
+                        todo!();
+                    }
+                    Type::State => {
+                        todo!();
+                    }
+                    Type::Action => {
+                        todo!();
+                    }
+                    Type::Bit(n) => {
+                        parameter_tokens.push(quote! {
+                            let #pname = p4rs::extract_bit_action_parameter(
+                                parameter_data,
+                                #offset,
+                                #n,
+                            );
+                        });
+                        parameter_refs.push(quote! { #pname.clone() });
+                        offset += n >> 3;
+                    }
+                    Type::Varbit(_n) => {
+                        todo!();
+                    }
+                    Type::Int(_n) => {
+                        todo!();
+                    }
+                    Type::String => {
+                        todo!();
+                    }
+                    Type::UserDefined(_s) => {
+                        todo!();
+                    }
+                    Type::ExternFunction => {
+                        todo!();
+                    }
+                    Type::HeaderMethod => {
+                        todo!();
+                    }
+                    Type::Table => {
+                        todo!();
+                    }
+                    Type::Void => {
+                        todo!();
+                    }
+                    Type::List(_) => {
+                        todo!();
+                    }
+                }
+            }
+            let mut control_params = Vec::new();
+            let mut control_param_types = Vec::new();
+            let mut action_params = Vec::new();
+            let mut action_param_types = Vec::new();
+            for p in &control.parameters {
+                let name = format_ident!("{}", p.name);
+                control_params.push(quote! { #name });
+                let ty = rust_type(&p.ty);
+                match p.direction {
+                    Direction::Out | Direction::InOut => {
+                        control_param_types.push(quote! { &mut #ty });
+                    }
+                    _ => {
+                        if p.ty == Type::Bool {
+                            control_param_types.push(quote! { #ty });
+                        } else {
+                            control_param_types.push(quote! { &#ty });
+                        }
+                    }
+                }
+            }
+
+            for p in &a.parameters {
+                let name = format_ident!("{}", p.name);
+                action_params.push(quote! { #name });
+                let ty = rust_type(&p.ty);
+                action_param_types.push(quote! { #ty });
+            }
+
+            for var in &control.variables {
+                let name = format_ident!("{}", var.name);
+                if let Type::UserDefined(typename) = &var.ty {
+                    if self.ast.get_extern(typename).is_some() {
+                        control_params.push(quote! { #name });
+                        let extern_type = format_ident!("{}", typename);
+                        control_param_types.push(quote! {
+                            &p4rs::externs::#extern_type
+                        });
+                    }
+                }
+            }
+
+            let aname = &action.name;
+            let tname = format_ident!("{}", qtfn);
+            action_match_body.extend(quote! {
+                #aname => {
+                    #(#parameter_tokens)*
+                    let action: std::sync::Arc<dyn Fn(
+                        #(#control_param_types),*
+                    )>
+                    = std::sync::Arc::new(move |
+                        #(#control_params),*
+                    | {
+                        #call(
+                            #(#control_params),*,
+                            #(#parameter_refs),*
+                        )
+                    });
+                    self.#tname
+                        .entries
+                        .insert(p4rs::table::TableEntry::<
+                            #n,
+                            std::sync::Arc<dyn Fn(
+                                #(#control_param_types),*
+                            )>,
+                        > {
+                            key,
+                            priority,
+                            name: "your name here".into(), //TODO
+                            action,
+                            action_id: #aname.to_owned(),
+                            parameter_data: parameter_data.to_owned(),
+                        });
+                }
+            });
+        }
+        let name = &control.name;
+        action_match_body.extend(quote! {
+            x => panic!("unknown {} action id {}", #name, x),
+        });
+
+        let name = format_ident!("add_{}_entry", qtfn);
+        quote! {
+            // lifetime is due to
+            // https://github.com/rust-lang/rust/issues/96771#issuecomment-1119886703
+            pub fn #name<'a>(
+                &mut self,
+                action_id: &str,
+                keyset_data: &'a [u8],
+                parameter_data: &'a [u8],
+                priority: u32,
+            ) {
+
+                let key = [#(#keys),*];
+
+                match action_id {
+                    #action_match_body
+                }
+
+            }
+        }
+    }
+
+    fn remove_table_entry_function(
+        &mut self,
+        table: &Table,
+        control: &Control,
+        qtfn: &str,
+    ) -> TokenStream {
+        let keys = self.table_entry_keys(table);
+        let n = table.key.len();
+
+        let tname = format_ident!("{}", qtfn);
+        let name = format_ident!("remove_{}_entry", qtfn);
+
+        let mut control_params = Vec::new();
+        let mut control_param_types = Vec::new();
+        for p in &control.parameters {
+            let name = format_ident!("{}", p.name);
+            control_params.push(quote! { #name });
+            let ty = rust_type(&p.ty);
+            match p.direction {
+                Direction::Out | Direction::InOut => {
+                    control_param_types.push(quote! { &mut #ty });
+                }
+                _ => {
+                    if p.ty == Type::Bool {
+                        control_param_types.push(quote! { #ty });
+                    } else {
+                        control_param_types.push(quote! { &#ty });
+                    }
+                }
+            }
+        }
+
+        for var in &control.variables {
+            let name = format_ident!("{}", var.name);
+            if let Type::UserDefined(typename) = &var.ty {
+                if self.ast.get_extern(typename).is_some() {
+                    control_params.push(quote! { #name });
+                    let extern_type = format_ident!("{}", typename);
+                    control_param_types.push(quote! {
+                        &p4rs::externs::#extern_type
+                    });
+                }
+            }
+        }
+
+        quote! {
+            // lifetime is due to
+            // https://github.com/rust-lang/rust/issues/96771#issuecomment-1119886703
+            pub fn #name<'a>(
+                &mut self,
+                keyset_data: &'a [u8],
+            ) {
+
+                let key = [#(#keys),*];
+
+                let action: std::sync::Arc<dyn Fn(
+                    #(#control_param_types),*
+                )>
+                = std::sync::Arc::new(move |
+                    #(#control_params),*
+                | { });
+
+                self.#tname
+                    .entries
+                    .remove(
+                        &p4rs::table::TableEntry::<
+                            #n,
+                            std::sync::Arc<dyn Fn(
+                                #(#control_param_types),*
+                            )>,
+                        > {
+                            key,
+                            priority: 0, //TODO
+                            name: "your name here".into(), //TODO
+                            action,
+                            action_id: String::new(),
+                            parameter_data: Vec::new(),
+                        }
+                    );
+
+            }
+        }
+    }
+
+    fn get_table_entries_function(
+        &mut self,
+        _table: &Table,
+        _control: &Control,
+        qtfn: &str,
+    ) -> TokenStream {
+        let name = format_ident!("get_{}_entries", qtfn);
+        let tname = format_ident!("{}", qtfn);
+
+        quote! {
+            pub fn #name(&self) -> Vec<p4rs::TableEntry> {
+                let mut result = Vec::new();
+
+                for e in &self.#tname.entries{
+
+                    let mut keyset_data = Vec::new();
+                    for k in &e.key {
+                        //TODO this is broken, to_bytes can squash N byte
+                        //objects into smaller than N bytes which violates
+                        //expectations of consumers. For example if this is a
+                        //16-bit integer with a value of 47 it will get squashed
+                        //down into 8-bits.
+                        keyset_data.extend_from_slice(&k.to_bytes());
+                    }
+
+                    let x = p4rs::TableEntry{
+                        action_id: e.action_id.clone(),
+                        keyset_data,
+                        parameter_data: e.parameter_data.clone(),
+                    };
+
+                    result.push(x);
+
+                }
+
+                result
+            }
+        }
+    }
+
+    pub(crate) fn parse_entrypoint(
+        &mut self,
+        parser: &Parser,
+    ) -> (TokenStream, TokenStream) {
+        // this should never happen here, if it does it's a bug in the checker.
+        let start_state = parser
+            .get_start_state()
+            .expect("parser must have start state");
+
+        let mut pg = crate::ParserGenerator::new(self.ast, self.hlir, self.ctx);
+        let (sig, _) = pg.generate_state_function(parser, start_state);
+
+        let member = quote! {
+            pub parse: fn #sig
+        };
+
+        let initializer = format_ident!("{}_start", parser.name);
+        (member, quote! { parse: #initializer })
+    }
+
+    pub(crate) fn control_entrypoint(
+        &mut self,
+        name: &str,
+        control: &Control,
+    ) -> (TokenStream, TokenStream) {
+        let mut cg =
+            crate::ControlGenerator::new(self.ast, self.hlir, self.ctx);
+        let (sig, _) = cg.generate_control(control);
+
+        let name = format_ident!("{}", name);
+
+        let member = quote! {
+            pub #name: fn #sig
+        };
+
+        let initializer = format_ident!("{}_apply", control.name);
+        (member, quote! { #name: #initializer })
+    }
+}
+
\ No newline at end of file diff --git a/src/p4_rust/statement.rs.html b/src/p4_rust/statement.rs.html new file mode 100644 index 00000000..647443e6 --- /dev/null +++ b/src/p4_rust/statement.rs.html @@ -0,0 +1,1223 @@ +statement.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+
// Copyright 2022 Oxide Computer Company
+
+use crate::{
+    expression::ExpressionGenerator, is_header, is_header_member,
+    is_rust_reference, rust_type,
+};
+use p4::ast::{
+    Call, Control, DeclarationInfo, Direction, ExpressionKind, NameInfo,
+    Parser, Statement, StatementBlock, Transition, Type, AST,
+};
+use p4::hlir::Hlir;
+use proc_macro2::TokenStream;
+use quote::{format_ident, quote};
+use std::collections::HashMap;
+
+#[derive(Debug)]
+pub(crate) enum StatementContext<'a> {
+    Control(&'a Control),
+    #[allow(dead_code)]
+    Parser(&'a Parser),
+}
+
+pub(crate) struct StatementGenerator<'a> {
+    hlir: &'a Hlir,
+    ast: &'a AST,
+    context: StatementContext<'a>,
+}
+
+impl<'a> StatementGenerator<'a> {
+    pub fn new(
+        ast: &'a AST,
+        hlir: &'a Hlir,
+        context: StatementContext<'a>,
+    ) -> Self {
+        Self { ast, hlir, context }
+    }
+
+    pub(crate) fn generate_block(
+        &self,
+        sb: &StatementBlock,
+        names: &mut HashMap<String, NameInfo>,
+    ) -> TokenStream {
+        let mut ts = TokenStream::new();
+        for stmt in &sb.statements {
+            ts.extend(self.generate_statement(stmt, names));
+        }
+        ts
+    }
+
+    pub(crate) fn generate_statement(
+        &self,
+        stmt: &Statement,
+        names: &mut HashMap<String, NameInfo>,
+    ) -> TokenStream {
+        match stmt {
+            Statement::Empty => TokenStream::new(),
+            Statement::Assignment(lval, xpr) => {
+                let eg = ExpressionGenerator::new(self.hlir);
+
+                let lhs = eg.generate_lvalue(lval);
+
+                let rhs = eg.generate_expression(xpr.as_ref());
+                let rhs_ty = self
+                    .hlir
+                    .expression_types
+                    .get(xpr.as_ref())
+                    .unwrap_or_else(|| {
+                        panic!("codegen type not found for {:#?}", xpr)
+                    });
+
+                let name_info =
+                    self.hlir.lvalue_decls.get(lval).unwrap_or_else(|| {
+                        panic!("codegen name not resolved for {:#?}", lval)
+                    });
+
+                if is_header_member(lval, self.hlir) {
+                    return quote! { #lhs = #rhs.clone(); };
+                }
+
+                let rhs = if rhs_ty != &name_info.ty {
+                    let converter = self.converter(rhs_ty, &name_info.ty);
+                    quote!( #converter(#rhs) )
+                } else {
+                    rhs
+                };
+
+                let rhs = if let Type::Bit(_) = rhs_ty {
+                    // TODO eww, to better to figure out precisely when to_owned
+                    // and clone are needed
+                    quote! { #rhs.to_owned().clone() }
+                } else if let Type::UserDefined(_) = rhs_ty {
+                    quote! { #rhs.clone() }
+                } else {
+                    rhs
+                };
+
+                if is_rust_reference(lval, names) {
+                    quote! { *#lhs = #rhs; }
+                } else {
+                    quote! { #lhs = #rhs; }
+                }
+            }
+            Statement::Call(c) => match &self.context {
+                StatementContext::Control(control) => {
+                    let mut ts = TokenStream::new();
+                    self.generate_control_body_call(control, c, &mut ts);
+                    ts
+                }
+                StatementContext::Parser(parser) => {
+                    let mut ts = TokenStream::new();
+                    self.generate_parser_body_call(parser, c, &mut ts);
+                    ts
+                }
+            },
+            Statement::If(ifb) => {
+                let eg = ExpressionGenerator::new(self.hlir);
+                let predicate = eg.generate_expression(ifb.predicate.as_ref());
+                let block = self.generate_block(&ifb.block, names);
+                let mut ts = quote! {
+                    if #predicate { #block }
+                };
+                for ei in &ifb.else_ifs {
+                    let predicate =
+                        eg.generate_expression(ei.predicate.as_ref());
+                    let block = self.generate_block(&ei.block, names);
+                    ts.extend(quote! {else if #predicate { #block }})
+                }
+                if let Some(eb) = &ifb.else_block {
+                    let block = self.generate_block(eb, names);
+                    ts.extend(quote! {else { #block }})
+                }
+                ts
+            }
+            Statement::Variable(v) => {
+                let name = format_ident!("{}", v.name);
+                let ty = rust_type(&v.ty);
+                let initializer = match &v.initializer {
+                    Some(xpr) => {
+                        let eg = ExpressionGenerator::new(self.hlir);
+                        let ini = eg.generate_expression(xpr.as_ref());
+                        let ini_ty =
+                            self.hlir.expression_types.get(xpr).unwrap_or_else(
+                                || panic!("type for expression {:#?}", xpr),
+                            );
+                        if ini_ty != &v.ty {
+                            let converter = self.converter(ini_ty, &v.ty);
+                            quote! { #converter(#ini) }
+                        } else {
+                            ini
+                        }
+                    }
+                    None => quote! { #ty::default() },
+                };
+                names.insert(
+                    v.name.clone(),
+                    NameInfo {
+                        ty: v.ty.clone(),
+                        decl: DeclarationInfo::Local,
+                    },
+                );
+
+                //TODO determine for real
+                let needs_mut = true;
+
+                if needs_mut {
+                    quote! {
+                        let mut #name: #ty = #initializer;
+                    }
+                } else {
+                    quote! {
+                        let #name: #ty = #initializer;
+                    }
+                }
+            }
+            Statement::Constant(c) => {
+                let name = format_ident!("{}", c.name);
+                let ty = rust_type(&c.ty);
+                let eg = ExpressionGenerator::new(self.hlir);
+                let initializer =
+                    eg.generate_expression(c.initializer.as_ref());
+                quote! {
+                    let #name: #ty = #initializer;
+                }
+            }
+            Statement::Transition(transition) => {
+                let parser = match self.context {
+                    StatementContext::Parser(p) => p,
+                    _ => {
+                        panic!(
+                            "transition statement outside parser: {:#?}",
+                            transition,
+                        )
+                    }
+                };
+                match transition {
+                    Transition::Reference(next_state) => {
+                        match next_state.name.as_str() {
+                            "accept" => quote! { return true; },
+                            "reject" => quote! { return false; },
+                            state_ref => {
+                                let state_name = format_ident!(
+                                    "{}_{}",
+                                    parser.name,
+                                    state_ref
+                                );
+                                let mut args = Vec::new();
+                                for arg in &parser.parameters {
+                                    let name = format_ident!("{}", arg.name);
+                                    args.push(quote! { #name });
+                                }
+                                quote! {
+                                    softnpu_provider::parser_transition!(||(#state_ref));
+                                    return #state_name( #(#args),* );
+                                }
+                            }
+                        }
+                    }
+                    Transition::Select(_) => {
+                        todo!();
+                    }
+                }
+            }
+            Statement::Return(xpr) => {
+                let eg = ExpressionGenerator::new(self.hlir);
+                if let Some(xpr) = xpr {
+                    let xp = eg.generate_expression(xpr.as_ref());
+                    quote! { return #xp; }
+                } else {
+                    quote! { return }
+                }
+            }
+        }
+    }
+
+    fn generate_parser_body_call(
+        &self,
+        parser: &Parser,
+        c: &Call,
+        tokens: &mut TokenStream,
+    ) {
+        let lval: Vec<TokenStream> = c
+            .lval
+            .name
+            .split('.')
+            .map(|x| format_ident!("{}", x))
+            .map(|x| quote! { #x })
+            .collect();
+
+        let mut args = Vec::new();
+        for a in &c.args {
+            match &a.kind {
+                ExpressionKind::Lvalue(lvarg) => {
+                    let parts: Vec<&str> = lvarg.name.split('.').collect();
+                    let root = parts[0];
+                    let mut mut_arg = false;
+                    for parg in &parser.parameters {
+                        if parg.name == root {
+                            match parg.direction {
+                                Direction::Out | Direction::InOut => {
+                                    mut_arg = true;
+                                }
+                                _ => {}
+                            }
+                        }
+                    }
+                    let lvref: Vec<TokenStream> = parts
+                        .iter()
+                        .map(|x| format_ident!("{}", x))
+                        .map(|x| quote! { #x })
+                        .collect();
+                    if mut_arg {
+                        args.push(quote! { &mut #(#lvref).* });
+                    } else {
+                        args.push(quote! { #(#lvref).* });
+                    }
+                }
+                x => todo!("extern arg {:?}", x),
+            }
+        }
+        tokens.extend(quote! {
+            #(#lval).* ( #(#args),* );
+        });
+    }
+
+    fn generate_control_body_call(
+        &self,
+        control: &Control,
+        c: &Call,
+        tokens: &mut TokenStream,
+    ) {
+        //
+        // get the lval reference to the thing being called
+        //
+        if c.lval.name.split('.').count() < 2 {
+            panic!(
+                "codegen: bare calls not supported, \
+                only <ref>.apply() calls are: {:#?}",
+                c
+            );
+        }
+        match c.lval.leaf() {
+            "apply" => {
+                self.generate_control_apply_body_call(control, c, tokens);
+            }
+            "setValid" => {
+                self.generate_header_set_validity(c, tokens, true);
+            }
+            "setInvalid" => {
+                self.generate_header_set_validity(c, tokens, false);
+            }
+            "isValid" => {
+                self.generate_header_get_validity(c, tokens);
+            }
+            _ => {
+                // assume we are at an extern call
+
+                // TODO check the extern call against defined externs in checker
+                // before we get here
+
+                self.generate_control_extern_call(control, c, tokens);
+            }
+        }
+    }
+
+    fn generate_control_extern_call(
+        &self,
+        _control: &Control,
+        c: &Call,
+        tokens: &mut TokenStream,
+    ) {
+        let eg = ExpressionGenerator::new(self.hlir);
+        let mut args = Vec::new();
+
+        for a in &c.args {
+            let arg_xpr = eg.generate_expression(a.as_ref());
+            args.push(arg_xpr);
+        }
+
+        let lvref: Vec<TokenStream> = c
+            .lval
+            .name
+            .split('.')
+            .map(|x| format_ident!("{}", x))
+            .map(|x| quote! { #x })
+            .collect();
+
+        tokens.extend(quote! {
+            #(#lvref).*(#(#args),*);
+        })
+    }
+
+    fn generate_control_apply_body_call(
+        &self,
+        control: &Control,
+        c: &Call,
+        tokens: &mut TokenStream,
+    ) {
+        let name_info = self
+            .hlir
+            .lvalue_decls
+            .get(&c.lval.pop_right())
+            .unwrap_or_else(|| {
+                panic!("codegen: lval root for {:#?} not found in hlir", c.lval)
+            });
+
+        let control_instance = match &name_info.ty {
+            Type::UserDefined(name) => {
+                self.ast.get_control(name).unwrap_or_else(|| {
+                    panic!("codegen: control {} not found in AST", name,)
+                })
+            }
+            Type::Table => control,
+            t => panic!("call references non-user-defined type {:#?}", t),
+        };
+
+        let root = c.lval.root();
+
+        // This is a call to another control instance
+        if control_instance.name != control.name {
+            let eg = ExpressionGenerator::new(self.hlir);
+            let mut locals = Vec::new();
+            let mut args = Vec::new();
+            for (i, a) in c.args.iter().enumerate() {
+                let arg_xpr = eg.generate_expression(a.as_ref());
+                let et = self.hlir.expression_types.get(a.as_ref()).unwrap();
+                let local_name = format_ident!("arg{}", i);
+                if let ExpressionKind::BitLit(_, _) = a.as_ref().kind {
+                    locals.push(quote! {
+                        let mut #local_name = #arg_xpr;
+                    })
+                }
+                match control_instance.parameters[i].direction {
+                    Direction::Out | Direction::InOut => {
+                        match &a.as_ref().kind {
+                            ExpressionKind::Lvalue(lval) => {
+                                let name_info = self
+                                    .hlir
+                                    .lvalue_decls
+                                    .get(lval)
+                                    .unwrap_or_else(|| {
+                                        panic!(
+                                        "codegen: lvalue resolve fail {:#?}",
+                                        lval
+                                    )
+                                    });
+                                match name_info.decl {
+                                    // if this is a control parameter, it should
+                                    // already have the correct reference
+                                    // annotations
+                                    DeclarationInfo::Parameter(_) => {
+                                        args.push(arg_xpr);
+                                    }
+                                    _ => {
+                                        args.push(quote! {&mut #arg_xpr});
+                                    }
+                                }
+                            }
+                            ExpressionKind::BitLit(_, _) => {
+                                args.push(quote! { &mut #local_name })
+                            }
+                            _ => {
+                                args.push(quote! {&mut #arg_xpr});
+                            }
+                        }
+                    }
+                    _ => match &a.as_ref().kind {
+                        ExpressionKind::BitLit(_, _) => {
+                            args.push(quote! { &#local_name })
+                        }
+                        // if the argument is an lvalue and a rust type that
+                        // gets passed by reference, take a ref
+                        ExpressionKind::Lvalue(_) => match et {
+                            Type::Bit(_) | Type::Varbit(_) | Type::Int(_) => {
+                                args.push(quote! { &#arg_xpr });
+                            }
+                            _ => {
+                                args.push(arg_xpr);
+                            }
+                        },
+                        _ => {
+                            args.push(arg_xpr);
+                        }
+                    },
+                }
+            }
+
+            let tables = control_instance.tables(self.ast);
+            for (cs, table) in tables {
+                let qtn =
+                    crate::qualified_table_function_name(None, &cs, table);
+                let name = format_ident!("{}_{}", c.lval.root(), qtn);
+                args.push(quote! { #name });
+            }
+
+            let cname = &control_instance.name;
+            let call = format_ident!("{}_apply", control_instance.name);
+
+            tokens.extend(quote! {
+                softnpu_provider::control_apply!(||(#cname));
+                #(#locals);*
+                #call(#(#args),*);
+            });
+
+            return;
+        }
+
+        // this is a local table
+
+        let table = match control_instance.get_table(root) {
+            Some(table) => table,
+            None => {
+                panic!(
+                    "codegen: table {} not found in control {} decl: {:#?}",
+                    root, control.name, name_info,
+                );
+            }
+        };
+
+        //
+        // match an action based on the key material
+        //
+
+        let table_name = format_ident!("{}", c.lval.root());
+
+        let table_name_str =
+            format!("{}_table_{}", control_instance.name, table.name,);
+
+        let mut action_args = Vec::new();
+        for p in &control.parameters {
+            let name = format_ident!("{}", p.name);
+            action_args.push(quote! { #name });
+        }
+
+        for var in &control.variables {
+            let name = format_ident!("{}", var.name);
+            if let Type::UserDefined(typename) = &var.ty {
+                if self.ast.get_extern(typename).is_some() {
+                    action_args.push(quote! { &#name });
+                }
+            }
+        }
+
+        let mut selector_components = Vec::new();
+        for (lval, _match_kind) in &table.key {
+            let lvref: Vec<TokenStream> = lval
+                .name
+                .split('.')
+                .map(|x| format_ident!("{}", x))
+                .map(|x| quote! { #x })
+                .collect();
+
+            // determine if this lvalue references a header or a struct,
+            // if it's a header there's a bit of extra unsrapping we
+            // need to do to match the selector against the value.
+
+            let names = control.names();
+
+            if lval.degree() > 1
+                && is_header(&lval.pop_right(), self.ast, &names)
+            {
+                //TODO: to_biguint is bad here, copying on data path
+                selector_components.push(quote! {
+                    p4rs::bitvec_to_biguint(
+                        &#(#lvref).*
+                    ).value
+                });
+            } else {
+                selector_components.push(quote! {
+                    p4rs::bitvec_to_biguint(&#(#lvref).*).value
+                });
+            }
+        }
+        let default_action =
+            format_ident!("{}_action_{}", control.name, table.default_action);
+        tokens.extend(quote! {
+            let matches = #table_name.match_selector(
+                &[#(#selector_components),*]
+            );
+            if matches.len() > 0 {
+                softnpu_provider::control_table_hit!(||#table_name_str);
+                (matches[0].action)(#(#action_args),*)
+            }
+        });
+        if table.default_action != "NoAction" {
+            tokens.extend(quote! {
+                else {
+                    softnpu_provider::control_table_miss!(||#table_name_str);
+                    #default_action(#(#action_args),*);
+                }
+            });
+        } else {
+            tokens.extend(quote! {
+                else {
+                    softnpu_provider::control_table_miss!(||#table_name_str);
+                }
+            });
+        }
+    }
+
+    fn generate_header_set_validity(
+        &self,
+        c: &Call,
+        tokens: &mut TokenStream,
+        valid: bool,
+    ) {
+        let lhs: Vec<TokenStream> = c
+            .lval
+            .pop_right()
+            .name
+            .split('.')
+            .map(|x| format_ident!("{}", x))
+            .map(|x| quote! { #x })
+            .collect();
+        if valid {
+            tokens.extend(quote! {
+                #(#lhs).*.set_valid();
+            });
+        } else {
+            tokens.extend(quote! {
+                #(#lhs).*.set_invalid();
+            });
+        }
+    }
+
+    fn generate_header_get_validity(&self, c: &Call, tokens: &mut TokenStream) {
+        let lhs: Vec<TokenStream> = c
+            .lval
+            .pop_right()
+            .name
+            .split('.')
+            .map(|x| format_ident!("{}", x))
+            .map(|x| quote! { #x })
+            .collect();
+        tokens.extend(quote! {
+            #(#lhs).*.is_valid()
+        });
+    }
+
+    fn converter(&self, from: &Type, to: &Type) -> TokenStream {
+        match (from, to) {
+            (Type::Int(_), Type::Bit(_)) => {
+                quote! { p4rs::int_to_bitvec }
+            }
+            (Type::Bit(x), Type::Bit(16)) if *x <= 16 => {
+                quote! { p4rs::bitvec_to_bitvec16 }
+            }
+            _ => todo!("type converter for {} to {}", from, to),
+        }
+    }
+}
+
\ No newline at end of file diff --git a/src/p4rs/bitmath.rs.html b/src/p4rs/bitmath.rs.html new file mode 100644 index 00000000..922a9025 --- /dev/null +++ b/src/p4rs/bitmath.rs.html @@ -0,0 +1,395 @@ +bitmath.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+
// Copyright 2022 Oxide Computer Company
+
+use bitvec::prelude::*;
+
+pub fn add_be(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0> {
+    let len = usize::max(a.len(), b.len());
+
+    // P4 spec says width limits are architecture defined, i here by define
+    // softnpu to have an architectural bit-type width limit of 128.
+    let x: u128 = a.load_be();
+    let y: u128 = b.load_be();
+    let z = x + y;
+    let mut c = BitVec::new();
+    c.resize(len, false);
+    c.store_be(z);
+    c
+}
+
+pub fn add_le(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0> {
+    let len = usize::max(a.len(), b.len());
+
+    // P4 spec says width limits are architecture defined, i here by define
+    // softnpu to have an architectural bit-type width limit of 128.
+    let x: u128 = a.load_le();
+    let y: u128 = b.load_le();
+    let z = x + y;
+    let mut c = BitVec::new();
+    c.resize(len, false);
+    c.store_le(z);
+    c
+}
+
+// leaving here in case we have a need for a true arbitrary-width adder.
+#[allow(dead_code)]
+pub fn add_generic(
+    a: BitVec<u8, Msb0>,
+    b: BitVec<u8, Msb0>,
+) -> BitVec<u8, Msb0> {
+    if a.len() != b.len() {
+        panic!("bitvec add size mismatch");
+    }
+    let mut c = BitVec::new();
+    c.resize(a.len(), false);
+
+    for i in (1..a.len()).rev() {
+        let y = c[i];
+        let x = a[i] ^ b[i];
+        if !(a[i] | b[i]) {
+            continue;
+        }
+        c.set(i, x ^ y);
+        let mut z = (a[i] && b[i]) | y;
+        for j in (1..i).rev() {
+            if !z {
+                break;
+            }
+            z = c[j];
+            c.set(j, true);
+        }
+    }
+
+    c
+}
+
+pub fn mod_be(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0> {
+    let len = usize::max(a.len(), b.len());
+
+    // P4 spec says width limits are architecture defined, i here by define
+    // softnpu to have an architectural bit-type width limit of 128.
+    let x: u128 = a.load_be();
+    let y: u128 = b.load_be();
+    let z = x % y;
+    let mut c = BitVec::new();
+    c.resize(len, false);
+    c.store_be(z);
+    c
+}
+
+pub fn mod_le(a: BitVec<u8, Msb0>, b: BitVec<u8, Msb0>) -> BitVec<u8, Msb0> {
+    let len = usize::max(a.len(), b.len());
+
+    // P4 spec says width limits are architecture defined, i here by define
+    // softnpu to have an architectural bit-type width limit of 128.
+    let x: u128 = a.load_le();
+    let y: u128 = b.load_le();
+    let z = x % y;
+    let mut c = BitVec::new();
+    c.resize(len, false);
+    c.store_le(z);
+    c
+}
+
+#[cfg(test)]
+mod tests {
+
+    #[test]
+    fn bitmath_add() {
+        use super::*;
+        let mut a = bitvec![mut u8, Msb0; 0; 16];
+        a.store_be(47);
+        let mut b = bitvec![mut u8, Msb0; 0; 16];
+        b.store_be(74);
+
+        println!("{:?}", a);
+        println!("{:?}", b);
+        let c = add_be(a, b);
+        println!("{:?}", c);
+
+        let cc: u128 = c.load_be();
+        assert_eq!(cc, 47u128 + 74u128);
+    }
+
+    #[test]
+    fn bitmath_add_mixed_size() {
+        use super::*;
+        let mut a = bitvec![mut u8, Msb0; 0; 8];
+        a.store_be(0xAB);
+        let mut b = bitvec![mut u8, Msb0; 0; 16];
+        b.store_be(0xCDE);
+
+        println!("{:?}", a);
+        println!("{:?}", b);
+        let c = add_be(a, b);
+        println!("{:?}", c);
+
+        let cc: u128 = c.load_be();
+        assert_eq!(cc, 0xABu128 + 0xCDEu128);
+    }
+
+    #[test]
+    fn bitmath_add_cascade() {
+        use super::*;
+        let mut a = bitvec![mut u8, Msb0; 0; 16];
+        a.store_be(47);
+        let mut b = bitvec![mut u8, Msb0; 0; 16];
+        b.store_be(74);
+        let mut c = bitvec![mut u8, Msb0; 0; 16];
+        c.store_be(123);
+        let mut d = bitvec![mut u8, Msb0; 0; 16];
+        d.store_be(9876);
+
+        let e = add_be(a, add_be(b, add_be(c, d)));
+
+        let ee: u128 = e.load_be();
+        assert_eq!(ee, 47u128 + 74u128 + 123u128 + 9876u128);
+    }
+
+    #[test]
+    fn bitmath_add_nest() {
+        use super::*;
+        let mut orig_l3_len = bitvec![mut u8, Msb0; 0; 16usize];
+        orig_l3_len.store_le(0xe9u128);
+        let x = add_le(
+            {
+                let mut x = bitvec![mut u8, Msb0; 0; 16usize];
+                x.store_le(14u128);
+                x
+            },
+            add_le(
+                orig_l3_len.clone(),
+                add_le(
+                    {
+                        let mut x = bitvec![mut u8, Msb0; 0; 16usize];
+                        x.store_le(8u128);
+                        x
+                    },
+                    {
+                        let mut x = bitvec![mut u8, Msb0; 0; 16usize];
+                        x.store_le(8u128);
+                        x
+                    },
+                ),
+            ),
+        );
+
+        let y: u128 = x.load_le();
+        assert_eq!(y, 0xe9 + 14 + 8 + 8);
+    }
+
+    #[test]
+    fn bitmath_mod() {
+        use super::*;
+        let mut a = bitvec![mut u8, Msb0; 0; 16];
+        a.store_be(47);
+        let mut b = bitvec![mut u8, Msb0; 0; 16];
+        b.store_be(7);
+
+        println!("{:?}", a);
+        println!("{:?}", b);
+        let c = mod_be(a, b);
+        println!("{:?}", c);
+
+        let cc: u128 = c.load_be();
+        assert_eq!(cc, 47u128 % 7u128);
+    }
+}
+
\ No newline at end of file diff --git a/src/p4rs/checksum.rs.html b/src/p4rs/checksum.rs.html new file mode 100644 index 00000000..fe22870e --- /dev/null +++ b/src/p4rs/checksum.rs.html @@ -0,0 +1,317 @@ +checksum.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+
// Copyright 2022 Oxide Computer Company
+
+use bitvec::prelude::*;
+
+#[derive(Default)]
+pub struct Csum(u16);
+
+impl Csum {
+    pub fn add(&mut self, a: u8, b: u8) {
+        let x = u16::from_be_bytes([a, b]);
+        let (mut result, overflow) = self.0.overflowing_add(x);
+        if overflow {
+            result += 1;
+        }
+        self.0 = result;
+    }
+    pub fn add128(&mut self, data: [u8; 16]) {
+        self.add(data[0], data[1]);
+        self.add(data[2], data[3]);
+        self.add(data[4], data[5]);
+        self.add(data[6], data[7]);
+        self.add(data[8], data[9]);
+        self.add(data[10], data[11]);
+        self.add(data[12], data[13]);
+        self.add(data[14], data[15]);
+    }
+    pub fn add32(&mut self, data: [u8; 4]) {
+        self.add(data[0], data[1]);
+        self.add(data[2], data[3]);
+    }
+    pub fn add16(&mut self, data: [u8; 2]) {
+        self.add(data[0], data[1]);
+    }
+    pub fn result(&self) -> u16 {
+        !self.0
+    }
+}
+
+pub fn udp6_checksum(data: &[u8]) -> u16 {
+    let src = &data[8..24];
+    let dst = &data[24..40];
+    let udp_len = &data[4..6];
+    let next_header = &data[6];
+    let src_port = &data[40..42];
+    let dst_port = &data[42..44];
+    let payload_len = &data[44..46];
+    let payload = &data[48..];
+
+    let mut csum = Csum(0);
+
+    for i in (0..src.len()).step_by(2) {
+        csum.add(src[i], src[i + 1]);
+    }
+    for i in (0..dst.len()).step_by(2) {
+        csum.add(dst[i], dst[i + 1]);
+    }
+    csum.add(udp_len[0], udp_len[1]);
+    //TODO assuming no jumbo
+    csum.add(0, *next_header);
+    csum.add(src_port[0], src_port[1]);
+    csum.add(dst_port[0], dst_port[1]);
+    csum.add(payload_len[0], payload_len[1]);
+
+    let len = payload.len();
+    let (odd, len) = if len % 2 == 0 {
+        (false, len)
+    } else {
+        (true, len - 1)
+    };
+    for i in (0..len).step_by(2) {
+        csum.add(payload[i], payload[i + 1]);
+    }
+    if odd {
+        csum.add(payload[len], 0);
+    }
+
+    csum.result()
+}
+
+pub trait Checksum {
+    fn csum(&self) -> BitVec<u8, Msb0>;
+}
+
+fn bvec_csum(bv: &BitVec<u8, Msb0>) -> BitVec<u8, Msb0> {
+    let x: u128 = bv.load();
+    let buf = x.to_be_bytes();
+    let mut c: u16 = 0;
+    for i in (0..16).step_by(2) {
+        c += u16::from_be_bytes([buf[i], buf[i + 1]])
+    }
+    let c = !c;
+    let mut result = bitvec![u8, Msb0; 0u8, 16];
+    result.store(c);
+    result
+}
+
+impl Checksum for BitVec<u8, Msb0> {
+    fn csum(&self) -> BitVec<u8, Msb0> {
+        bvec_csum(self)
+    }
+}
+
+impl Checksum for &BitVec<u8, Msb0> {
+    fn csum(&self) -> BitVec<u8, Msb0> {
+        bvec_csum(self)
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+    use pnet::packet::udp;
+    use std::f32::consts::PI;
+    use std::net::Ipv6Addr;
+
+    #[test]
+    fn udp_checksum() {
+        let mut packet = [0u8; 200];
+
+        //
+        // ipv6
+        //
+
+        packet[0] = 6; // version = 6
+        packet[5] = 160; // 160 byte payload (200 - payload=40)
+        packet[6] = 17; // next header = udp
+        packet[7] = 255; // hop limit = 255
+
+        // src = fd00::1
+        packet[8] = 0xfd;
+        packet[23] = 0x01;
+
+        // dst = fd00::2
+        packet[24] = 0xfd;
+        packet[39] = 0x02;
+
+        //
+        // udp
+        //
+
+        packet[41] = 47; // source port = 47
+        packet[43] = 74; // dstination port = 74
+        packet[45] = 160; // udp header + payload = 160 bytes
+        for (i, data_point) in packet.iter_mut().enumerate().skip(46) {
+            *data_point = ((i as f32) * (PI / 32.0) * 10.0) as u8;
+        }
+
+        let x = udp6_checksum(&packet);
+
+        let p = udp::UdpPacket::new(&packet[40..]).unwrap();
+        let src: Ipv6Addr = "fd00::1".parse().unwrap();
+        let dst: Ipv6Addr = "fd00::2".parse().unwrap();
+        let y = udp::ipv6_checksum(&p, &src, &dst);
+
+        assert_eq!(x, y);
+    }
+}
+
\ No newline at end of file diff --git a/src/p4rs/error.rs.html b/src/p4rs/error.rs.html new file mode 100644 index 00000000..b85f21fc --- /dev/null +++ b/src/p4rs/error.rs.html @@ -0,0 +1,33 @@ +error.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+
// Copyright 2022 Oxide Computer Company
+
+use std::error::Error;
+use std::fmt;
+
+#[derive(Debug)]
+pub struct TryFromSliceError(pub usize);
+
+impl fmt::Display for TryFromSliceError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "slice not big enough for {} bits", self.0)
+    }
+}
+
+impl Error for TryFromSliceError {}
+
\ No newline at end of file diff --git a/src/p4rs/externs.rs.html b/src/p4rs/externs.rs.html new file mode 100644 index 00000000..b0e67992 --- /dev/null +++ b/src/p4rs/externs.rs.html @@ -0,0 +1,65 @@ +externs.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+
// Copyright 2022 Oxide Computer Company
+
+use bitvec::prelude::*;
+
+pub struct Checksum {}
+
+impl Checksum {
+    pub fn new() -> Self {
+        Self {}
+    }
+
+    pub fn run(
+        &self,
+        elements: &[&dyn crate::checksum::Checksum],
+    ) -> BitVec<u8, Msb0> {
+        let mut csum: u16 = 0;
+        for e in elements {
+            let c: u16 = e.csum().load();
+            csum += c;
+        }
+        let mut result = bitvec![u8, Msb0; 0u8, 16];
+        result.store(csum);
+        result
+    }
+}
+
+impl Default for Checksum {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
\ No newline at end of file diff --git a/src/p4rs/lib.rs.html b/src/p4rs/lib.rs.html new file mode 100644 index 00000000..bb470919 --- /dev/null +++ b/src/p4rs/lib.rs.html @@ -0,0 +1,763 @@ +lib.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+
// Copyright 2022 Oxide Computer Company
+
+//! This is the runtime support create for `x4c` generated programs.
+//!
+//! The main abstraction in this crate is the [`Pipeline`] trait. Rust code that
+//! is generated by `x4c` implements this trait. A `main_pipeline` struct is
+//! exported by the generated code that implements [`Pipeline`]. Users can wrap
+//! the `main_pipeline` object in harness code to provide higher level
+//! interfaces for table manipulation and packet i/o.
+//!
+//! ```rust
+//! use p4rs::{ packet_in, packet_out, Pipeline };
+//! use std::net::Ipv6Addr;
+//!
+//! struct Handler {
+//!     pipe: Box<dyn Pipeline>
+//! }
+//!
+//! impl Handler {
+//!     /// Create a new pipeline handler.
+//!     fn new(pipe: Box<dyn Pipeline>) -> Self {
+//!         Self{ pipe }
+//!     }
+//!
+//!     /// Handle a packet from the specified port. If the pipeline produces
+//!     /// an output result, send the processed packet to the output port
+//!     /// returned by the pipeline.
+//!     fn handle_packet(&mut self, port: u16, pkt: &[u8]) {
+//!
+//!         let mut input = packet_in::new(pkt);
+//!
+//!         let output =  self.pipe.process_packet(port, &mut input);
+//!         for (out_pkt, out_port) in &output {
+//!             let mut out = out_pkt.header_data.clone();
+//!             out.extend_from_slice(out_pkt.payload_data);
+//!             self.send_packet(*out_port, &out);
+//!         }
+//!
+//!     }
+//!
+//!     /// Add a routing table entry. Packets for the provided destination will
+//!     /// be sent out the specified port.
+//!     fn add_router_entry(&mut self, dest: Ipv6Addr, port: u16) {
+//!         self.pipe.add_table_entry(
+//!             "ingress.router.ipv6_routes", // qualified name of the table
+//!             "forward_out_port",           // action to invoke on a hit
+//!             &dest.octets(),
+//!             &port.to_le_bytes(),
+//!             0,
+//!         );
+//!     }
+//!
+//!     /// Send a packet out the specified port.
+//!     fn send_packet(&self, port: u16, pkt: &[u8]) {
+//!         // send the packet ...
+//!     }
+//! }
+//! ```
+//!
+#![allow(incomplete_features)]
+#![allow(non_camel_case_types)]
+
+use std::fmt;
+use std::net::IpAddr;
+
+pub use error::TryFromSliceError;
+use serde::{Deserialize, Serialize};
+
+use bitvec::prelude::*;
+
+pub mod error;
+//pub mod hicuts;
+//pub mod rice;
+pub mod bitmath;
+pub mod checksum;
+pub mod externs;
+pub mod table;
+
+#[usdt::provider]
+mod p4rs_provider {
+    fn match_miss(_: &str) {}
+}
+
+#[derive(Debug)]
+pub struct Bit<'a, const N: usize>(pub &'a [u8]);
+
+impl<'a, const N: usize> Bit<'a, N> {
+    //TODO measure the weight of returning TryFromSlice error versus just
+    //dropping and incrementing a counter. Relying on dtrace for more detailed
+    //debugging.
+    pub fn new(data: &'a [u8]) -> Result<Self, TryFromSliceError> {
+        let required_bytes = if N & 7 > 0 { (N >> 3) + 1 } else { N >> 3 };
+        if data.len() < required_bytes {
+            return Err(TryFromSliceError(N));
+        }
+        Ok(Self(&data[..required_bytes]))
+    }
+}
+
+impl<'a, const N: usize> fmt::LowerHex for Bit<'a, N> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        for x in self.0 {
+            fmt::LowerHex::fmt(&x, f)?;
+        }
+        Ok(())
+    }
+}
+
+// TODO more of these for other sizes
+impl<'a> From<Bit<'a, 16>> for u16 {
+    fn from(b: Bit<'a, 16>) -> u16 {
+        u16::from_be_bytes([b.0[0], b.0[1]])
+    }
+}
+
+// TODO more of these for other sizes
+impl<'a> std::hash::Hash for Bit<'a, 8> {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.0[0].hash(state);
+    }
+}
+
+impl<'a> std::cmp::PartialEq for Bit<'a, 8> {
+    fn eq(&self, other: &Self) -> bool {
+        self.0[0] == other.0[0]
+    }
+}
+
+impl<'a> std::cmp::Eq for Bit<'a, 8> {}
+
+/// Every packet that goes through a P4 pipeline is represented as a `packet_in`
+/// instance. `packet_in` objects wrap an underlying mutable data reference that
+/// is ultimately rooted in a memory mapped region containing a ring of packets.
+#[derive(Debug)]
+pub struct packet_in<'a> {
+    /// The underlying data. Owned by an external, memory-mapped packet ring.
+    pub data: &'a [u8],
+
+    /// Extraction index. Everything before `index` has been extracted already.
+    /// Only data after `index` is eligble for extraction. Extraction is always
+    /// for contiguous segments of the underlying packet ring data.
+    pub index: usize,
+}
+
+#[derive(Debug)]
+pub struct packet_out<'a> {
+    pub header_data: Vec<u8>,
+    pub payload_data: &'a [u8],
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+pub struct TableEntry {
+    pub action_id: String,
+    pub keyset_data: Vec<u8>,
+    pub parameter_data: Vec<u8>,
+}
+
+pub trait Pipeline: Send {
+    /// Process an input packet and produce a set of output packets. Normally
+    /// there will be a single output packet. However, if the pipeline sets
+    /// `egress_metadata_t.broadcast` there may be multiple output packets.
+    fn process_packet<'a>(
+        &mut self,
+        port: u16,
+        pkt: &mut packet_in<'a>,
+    ) -> Vec<(packet_out<'a>, u16)>;
+
+    //TODO use struct TableEntry?
+    /// Add an entry to a table identified by table_id.
+    fn add_table_entry(
+        &mut self,
+        table_id: &str,
+        action_id: &str,
+        keyset_data: &[u8],
+        parameter_data: &[u8],
+        priority: u32,
+    );
+
+    /// Remove an entry from a table identified by table_id.
+    fn remove_table_entry(&mut self, table_id: &str, keyset_data: &[u8]);
+
+    /// Get all the entries in a table.
+    fn get_table_entries(&self, table_id: &str) -> Option<Vec<TableEntry>>;
+
+    /// Get a list of table ids
+    fn get_table_ids(&self) -> Vec<&str>;
+}
+
+/// A fixed length header trait.
+pub trait Header {
+    fn new() -> Self;
+    fn size() -> usize;
+    fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>;
+    fn set_valid(&mut self);
+    fn set_invalid(&mut self);
+    fn is_valid(&self) -> bool;
+    fn to_bitvec(&self) -> BitVec<u8, Msb0>;
+}
+
+impl<'a> packet_in<'a> {
+    pub fn new(data: &'a [u8]) -> Self {
+        Self { data, index: 0 }
+    }
+
+    // TODO: this function signature is a bit unforunate in the sense that the
+    // p4 compiler generates call sites based on a p4 `packet_in` extern
+    // definition. But based on that definition, there is no way for the
+    // compiler to know that this function returns a result that needs to be
+    // interrogated. In fact, the signature for packet_in::extract from the p4
+    // standard library requires the return type to be `void`, so this signature
+    // cannot return a result without the compiler having special knowledge of
+    // functions that happen to be called "extract".
+    pub fn extract<H: Header>(&mut self, h: &mut H) {
+        //TODO what if a header does not end on a byte boundary?
+        let n = H::size();
+        let start = if self.index > 0 { self.index >> 3 } else { 0 };
+        match h.set(&self.data[start..start + (n >> 3)]) {
+            Ok(_) => {}
+            Err(e) => {
+                //TODO better than this
+                println!("packet extraction failed: {}", e);
+            }
+        }
+        self.index += n;
+        h.set_valid();
+    }
+
+    // This is the same as extract except we return a new header instead of
+    // modifying an existing one.
+    pub fn extract_new<H: Header>(&mut self) -> Result<H, TryFromSliceError> {
+        let n = H::size();
+        let start = if self.index > 0 { self.index >> 3 } else { 0 };
+        self.index += n;
+        let mut x = H::new();
+        x.set(&self.data[start..start + (n >> 3)])?;
+        Ok(x)
+    }
+}
+
+//XXX: remove once classifier defined in terms of bitvecs
+pub fn bitvec_to_biguint(bv: &BitVec<u8, Msb0>) -> table::BigUintKey {
+    let s = bv.as_raw_slice();
+    table::BigUintKey {
+        value: num::BigUint::from_bytes_le(s),
+        width: s.len(),
+    }
+}
+
+pub fn bitvec_to_ip6addr(bv: &BitVec<u8, Msb0>) -> std::net::IpAddr {
+    let mut arr: [u8; 16] = bv.as_raw_slice().try_into().unwrap();
+    arr.reverse();
+    std::net::IpAddr::V6(std::net::Ipv6Addr::from(arr))
+}
+
+#[repr(C, align(16))]
+pub struct AlignedU128(pub u128);
+
+pub fn int_to_bitvec(x: i128) -> BitVec<u8, Msb0> {
+    //let mut bv = BitVec::<u8, Msb0>::new();
+    let mut bv = bitvec![mut u8, Msb0; 0; 128];
+    bv.store(x);
+    bv
+}
+
+pub fn bitvec_to_bitvec16(mut x: BitVec<u8, Msb0>) -> BitVec<u8, Msb0> {
+    x.resize(16, false);
+    x
+}
+
+pub fn dump_bv(x: &BitVec<u8, Msb0>) -> String {
+    if x.is_empty() {
+        "∅".into()
+    } else {
+        let v: u128 = x.load_le();
+        format!("{:x}", v)
+    }
+}
+
+pub fn extract_exact_key(
+    keyset_data: &[u8],
+    offset: usize,
+    len: usize,
+) -> table::Key {
+    table::Key::Exact(table::BigUintKey {
+        value: num::BigUint::from_bytes_le(&keyset_data[offset..offset + len]),
+        width: len,
+    })
+}
+
+pub fn extract_range_key(
+    keyset_data: &[u8],
+    offset: usize,
+    len: usize,
+) -> table::Key {
+    table::Key::Range(
+        table::BigUintKey {
+            value: num::BigUint::from_bytes_le(
+                &keyset_data[offset..offset + len],
+            ),
+            width: len,
+        },
+        table::BigUintKey {
+            value: num::BigUint::from_bytes_le(
+                &keyset_data[offset + len..offset + len + len],
+            ),
+            width: len,
+        },
+    )
+}
+
+/// Extract a ternary key from the provided keyset data. Ternary keys come in
+/// two parts. The first part is a leading bit that indicates whether we care
+/// about the value. If that leading bit is non-zero, the trailing bits of the
+/// key are interpreted as a binary value. If the leading bit is zero, the
+/// trailing bits are ignored and a Ternary::DontCare key is returned.
+pub fn extract_ternary_key(
+    keyset_data: &[u8],
+    offset: usize,
+    len: usize,
+) -> table::Key {
+    let care = keyset_data[offset];
+    if care != 0 {
+        table::Key::Ternary(table::Ternary::Value(table::BigUintKey {
+            value: num::BigUint::from_bytes_le(
+                &keyset_data[offset + 1..offset + 1 + len],
+            ),
+            width: len,
+        }))
+    } else {
+        table::Key::Ternary(table::Ternary::DontCare)
+    }
+}
+
+pub fn extract_lpm_key(
+    keyset_data: &[u8],
+    offset: usize,
+    _len: usize,
+) -> table::Key {
+    let (addr, len) = match keyset_data.len() {
+        // IPv4
+        5 => {
+            let data: [u8; 4] =
+                keyset_data[offset..offset + 4].try_into().unwrap();
+            (IpAddr::from(data), keyset_data[offset + 4])
+        }
+        // IPv6
+        17 => {
+            let data: [u8; 16] =
+                keyset_data[offset..offset + 16].try_into().unwrap();
+            (IpAddr::from(data), keyset_data[offset + 16])
+        }
+        x => {
+            panic!("lpm: key must be len 5 (ipv4) or 17 (ipv6) found {}", x);
+        }
+    };
+
+    table::Key::Lpm(table::Prefix { addr, len })
+}
+
+pub fn extract_bool_action_parameter(
+    parameter_data: &[u8],
+    offset: usize,
+) -> bool {
+    parameter_data[offset] == 1
+}
+
+pub fn extract_bit_action_parameter(
+    parameter_data: &[u8],
+    offset: usize,
+    size: usize,
+) -> BitVec<u8, Msb0> {
+    let mut byte_size = size >> 3;
+    if size % 8 != 0 {
+        byte_size += 1;
+    }
+    let mut b: BitVec<u8, Msb0> =
+        BitVec::from_slice(&parameter_data[offset..offset + byte_size]);
+    b.resize(size, false);
+    b
+}
+
\ No newline at end of file diff --git a/src/p4rs/table.rs.html b/src/p4rs/table.rs.html new file mode 100644 index 00000000..efd36557 --- /dev/null +++ b/src/p4rs/table.rs.html @@ -0,0 +1,1697 @@ +table.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+
// Copyright 2022 Oxide Computer Company
+
+use std::collections::HashSet;
+use std::fmt::Write;
+use std::net::IpAddr;
+
+use num::bigint::BigUint;
+use num::ToPrimitive;
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
+pub struct BigUintKey {
+    pub value: BigUint,
+    pub width: usize,
+}
+
+// TODO transition from BigUint to BitVec<u8, Msb0>, this requires being able to
+// do a number of mathematical operations on BitVec<u8, Msb0>.
+#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
+pub enum Key {
+    Exact(BigUintKey),
+    Range(BigUintKey, BigUintKey),
+    Ternary(Ternary),
+    Lpm(Prefix),
+}
+
+impl Default for Key {
+    fn default() -> Self {
+        Self::Ternary(Ternary::default())
+    }
+}
+
+impl Key {
+    pub fn to_bytes(&self) -> Vec<u8> {
+        match self {
+            Key::Exact(x) => {
+                let mut buf = x.value.to_bytes_le();
+
+                // A value serialized from a BigUint may be less than the width of a
+                // field. For example a 16-bit field with with a value of 47 will come
+                // back in 8 bits from BigUint serialization.
+                buf.resize(x.width, 0);
+                buf
+            }
+            Key::Range(a, z) => {
+                let mut buf_a = a.value.to_bytes_le();
+                let mut buf_z = z.value.to_bytes_le();
+
+                buf_a.resize(a.width, 0);
+                buf_z.resize(z.width, 0);
+                buf_a.extend_from_slice(&buf_z);
+                buf_a
+            }
+            Key::Ternary(t) => match t {
+                Ternary::DontCare => {
+                    let mut buf = Vec::new();
+                    buf.clear();
+                    buf
+                }
+                Ternary::Value(v) => {
+                    let mut buf = v.value.to_bytes_le();
+                    buf.resize(v.width, 0);
+                    buf
+                }
+                Ternary::Masked(v, m, w) => {
+                    let mut buf_a = v.to_bytes_le();
+                    let mut buf_b = m.to_bytes_le();
+                    buf_a.resize(*w, 0);
+                    buf_b.resize(*w, 0);
+                    buf_a.extend_from_slice(&buf_b);
+                    buf_a
+                }
+            },
+            Key::Lpm(p) => {
+                let mut v: Vec<u8> = match p.addr {
+                    IpAddr::V4(a) => a.octets().into(),
+                    IpAddr::V6(a) => a.octets().into(),
+                };
+                v.push(p.len);
+                v
+            }
+        }
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
+pub enum Ternary {
+    DontCare,
+    Value(BigUintKey),
+    Masked(BigUint, BigUint, usize),
+}
+
+impl Default for Ternary {
+    fn default() -> Self {
+        Self::DontCare
+    }
+}
+
+#[derive(Debug, Clone, PartialEq, Hash, Eq, Serialize, Deserialize)]
+pub struct Prefix {
+    pub addr: IpAddr,
+    pub len: u8,
+}
+
+pub struct Table<const D: usize, A: Clone> {
+    pub entries: HashSet<TableEntry<D, A>>,
+}
+
+impl<const D: usize, A: Clone> Default for Table<D, A> {
+    fn default() -> Self {
+        Self::new()
+    }
+}
+
+impl<const D: usize, A: Clone> Table<D, A> {
+    pub fn new() -> Self {
+        Self {
+            entries: HashSet::new(),
+        }
+    }
+
+    pub fn match_selector(
+        &self,
+        keyset: &[BigUint; D],
+    ) -> Vec<TableEntry<D, A>> {
+        let mut result = Vec::new();
+        for entry in &self.entries {
+            if keyset_matches(keyset, &entry.key) {
+                result.push(entry.clone());
+            }
+        }
+        sort_entries(result)
+    }
+
+    pub fn dump(&self) -> String {
+        let mut s = String::new();
+        for e in &self.entries {
+            writeln!(s, "{:?}", e.key).unwrap();
+        }
+        s
+    }
+}
+
+// Sort a vector of match result entries. Do not apply this sort function to
+// general vectors of entries, it only works for matching results. Specifically
+// the entries are pruned to longest prefix matches.
+pub fn sort_entries<const D: usize, A: Clone>(
+    mut entries: Vec<TableEntry<D, A>>,
+) -> Vec<TableEntry<D, A>> {
+    if entries.is_empty() {
+        return entries;
+    }
+
+    // First determine how to sort. All the entries have the same keyset
+    // structure, so it's sufficient to iterate over the keys of the first
+    // entry. The basic logic we follow here is
+    //
+    // - If we find an lpm key sort on the prefix lenght of that dimension.
+    // - Otherwise simply sort on priority.
+    //
+    // Notes:
+    //
+    // It's assumed that multiple lpm keys do not exist in a single keyset.
+    // This is an implicit assumption in BVM2
+    //
+    //      https://github.com/p4lang/behavioral-model/issues/698
+    //
+    for (i, k) in entries[0].key.iter().enumerate() {
+        match k {
+            Key::Lpm(_) => {
+                let mut entries = prune_entries_by_lpm(i, &entries);
+                sort_entries_by_priority(&mut entries);
+                return entries;
+            }
+            _ => continue,
+        }
+    }
+
+    sort_entries_by_priority(&mut entries);
+    entries
+}
+
+// TODO - the data structures here are quite dumb. The point of this table
+// implemntation is not efficiency, it's a simple bruteish apprach that is easy
+// to move around until we nail down the, tbh, rather undefined (in terms of p4
+// spec)semantics of what the relative priorities between match types in a
+// common keyset are.
+pub fn prune_entries_by_lpm<const D: usize, A: Clone>(
+    d: usize,
+    entries: &Vec<TableEntry<D, A>>,
+) -> Vec<TableEntry<D, A>> {
+    let mut longest_prefix = 0u8;
+
+    for e in entries {
+        if let Key::Lpm(x) = &e.key[d] {
+            if x.len > longest_prefix {
+                longest_prefix = x.len
+            }
+        }
+    }
+
+    let mut result = Vec::new();
+    for e in entries {
+        if let Key::Lpm(x) = &e.key[d] {
+            if x.len == longest_prefix {
+                result.push(e.clone())
+            }
+        }
+    }
+
+    result
+}
+
+pub fn sort_entries_by_priority<const D: usize, A: Clone>(
+    entries: &mut [TableEntry<D, A>],
+) {
+    entries
+        .sort_by(|a, b| -> std::cmp::Ordering { b.priority.cmp(&a.priority) });
+}
+
+pub fn key_matches(selector: &BigUint, key: &Key) -> bool {
+    match key {
+        Key::Exact(x) => {
+            let hit = selector == &x.value;
+            if !hit {
+                let dump = format!("{:x} != {:x}", selector, x.value);
+                crate::p4rs_provider::match_miss!(|| &dump);
+            }
+            hit
+        }
+        Key::Range(begin, end) => {
+            let hit = selector >= &begin.value && selector <= &end.value;
+            if !hit {
+                let dump = format!(
+                    "begin={} end={} sel={}",
+                    begin.value, end.value, selector
+                );
+                crate::p4rs_provider::match_miss!(|| &dump);
+            }
+            hit
+        }
+        Key::Ternary(t) => match t {
+            Ternary::DontCare => true,
+            Ternary::Value(x) => selector == &x.value,
+            Ternary::Masked(x, m, _) => selector & m == x & m,
+        },
+        Key::Lpm(p) => match p.addr {
+            IpAddr::V6(addr) => {
+                assert!(p.len <= 128);
+                let key: u128 = addr.into();
+                let mask = if p.len == 128 {
+                    u128::MAX
+                } else if p.len == 0 {
+                    0u128
+                } else {
+                    ((1u128 << p.len) - 1) << (128 - p.len)
+                };
+                //let mask = mask.to_be();
+                let selector_v6 = selector.to_u128().unwrap();
+                let hit = selector_v6 & mask == key & mask;
+                if !hit {
+                    let dump = format!(
+                        "{:x} & {:x} == {:x} & {:x} | {:x} == {:x}",
+                        selector_v6,
+                        mask,
+                        key,
+                        mask,
+                        selector_v6 & mask,
+                        key & mask
+                    );
+                    //println!("{}", dump);
+                    crate::p4rs_provider::match_miss!(|| &dump);
+                }
+                hit
+            }
+            IpAddr::V4(addr) => {
+                assert!(p.len <= 32);
+                let key: u32 = addr.into();
+                let mask = if p.len == 32 {
+                    u32::MAX
+                } else if p.len == 0 {
+                    0
+                } else {
+                    ((1u32 << p.len) - 1) << (32 - p.len)
+                };
+                let selector_v4: u32 = selector.to_u32().unwrap();
+                let hit = selector_v4 & mask == key & mask;
+                if !hit {
+                    let dump = format!(
+                        "{:x} & {:x} == {:x} & {:x} | {:x} = {:x}",
+                        selector_v4,
+                        mask,
+                        key,
+                        mask,
+                        selector_v4 & mask,
+                        key & mask
+                    );
+                    crate::p4rs_provider::match_miss!(|| &dump);
+                }
+                hit
+            }
+        },
+    }
+}
+
+pub fn keyset_matches<const D: usize>(
+    selector: &[BigUint; D],
+    key: &[Key; D],
+) -> bool {
+    for i in 0..D {
+        if !key_matches(&selector[i], &key[i]) {
+            return false;
+        }
+    }
+    true
+}
+
+#[derive(Clone)]
+pub struct TableEntry<const D: usize, A: Clone> {
+    pub key: [Key; D],
+    pub action: A,
+    pub priority: u32,
+    pub name: String,
+
+    // the following are not used operationally, strictly for observability as
+    // the closure contained in `A` is hard to get at.
+    pub action_id: String,
+    pub parameter_data: Vec<u8>,
+}
+
+// TODO: Cannot hash on just the key, this does not work for multipath.
+impl<const D: usize, A: Clone> std::hash::Hash for TableEntry<D, A> {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.key.hash(state);
+    }
+}
+
+impl<const D: usize, A: Clone> std::cmp::PartialEq for TableEntry<D, A> {
+    fn eq(&self, other: &Self) -> bool {
+        self.key == other.key
+    }
+}
+
+impl<const D: usize, A: Clone> std::fmt::Debug for TableEntry<D, A> {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        f.debug_struct(&format!("TableEntry<{}>", D))
+            .field("key", &self.key)
+            .field("priority", &self.priority)
+            .field("name", &self.name)
+            .finish()
+    }
+}
+
+impl<const D: usize, A: Clone> std::cmp::Eq for TableEntry<D, A> {}
+
+#[cfg(test)]
+mod tests {
+
+    use super::*;
+    use std::net::Ipv6Addr;
+    use std::sync::Arc;
+
+    fn contains_entry<const D: usize, A: Clone>(
+        entries: &Vec<TableEntry<D, A>>,
+        name: &str,
+    ) -> bool {
+        for e in entries {
+            if e.name.as_str() == name {
+                return true;
+            }
+        }
+        false
+    }
+
+    fn tk(
+        name: &str,
+        addr: Ternary,
+        ingress: Ternary,
+        icmp: Ternary,
+        priority: u32,
+    ) -> TableEntry<3, ()> {
+        TableEntry::<3, ()> {
+            key: [
+                Key::Ternary(addr),
+                Key::Ternary(ingress),
+                Key::Ternary(icmp),
+            ],
+            priority,
+            name: name.into(),
+            action: (),
+            action_id: String::new(),
+            parameter_data: Vec::new(),
+        }
+    }
+
+    #[test]
+    /// A few tests on the following table.
+    ///
+    /// +--------+-------------+--------------+---------+
+    /// | Action | switch addr | ingress port | is icmp |
+    /// +--------+-------------+--------------+---------+
+    /// | a0     | true        | _            | true    |
+    /// | a1     | true        | _            | false   |
+    /// | a2     | _           | 2            | _       |
+    /// | a3     | _           | 4            | _       |
+    /// | a4     | _           | 7            | _       |
+    /// | a5     | _           | 19           | _       |
+    /// | a6     | _           | 33           | _       |
+    /// | a7     | _           | 47           | _       |
+    /// +--------+-------------+--------------+---------+
+    fn match_ternary_1() {
+        let table = Table::<3, ()> {
+            entries: HashSet::from([
+                tk(
+                    "a0",
+                    Ternary::Value(BigUintKey {
+                        value: 1u8.into(),
+                        width: 1,
+                    }),
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 1u8.into(),
+                        width: 1,
+                    }),
+                    10,
+                ),
+                tk(
+                    "a1",
+                    Ternary::Value(BigUintKey {
+                        value: 1u8.into(),
+                        width: 1,
+                    }),
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 0u8.into(),
+                        width: 1,
+                    }),
+                    1,
+                ),
+                tk(
+                    "a2",
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 2u16.into(),
+                        width: 2,
+                    }),
+                    Ternary::DontCare,
+                    1,
+                ),
+                tk(
+                    "a3",
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 4u16.into(),
+                        width: 2,
+                    }),
+                    Ternary::DontCare,
+                    1,
+                ),
+                tk(
+                    "a4",
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 7u16.into(),
+                        width: 2,
+                    }),
+                    Ternary::DontCare,
+                    1,
+                ),
+                tk(
+                    "a5",
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 19u16.into(),
+                        width: 2,
+                    }),
+                    Ternary::DontCare,
+                    1,
+                ),
+                tk(
+                    "a6",
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 33u16.into(),
+                        width: 2,
+                    }),
+                    Ternary::DontCare,
+                    1,
+                ),
+                tk(
+                    "a7",
+                    Ternary::DontCare,
+                    Ternary::Value(BigUintKey {
+                        value: 47u16.into(),
+                        width: 2,
+                    }),
+                    Ternary::DontCare,
+                    1,
+                ),
+            ]),
+        };
+
+        //println!("M1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+        let selector =
+            [BigUint::from(1u8), BigUint::from(99u16), BigUint::from(1u8)];
+        let matches = table.match_selector(&selector);
+        //println!("{:#?}", matches);
+        assert_eq!(matches.len(), 1);
+        assert!(contains_entry(&matches, "a0"));
+
+        //println!("M2 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
+        let selector =
+            [BigUint::from(1u8), BigUint::from(47u16), BigUint::from(1u8)];
+        let matches = table.match_selector(&selector);
+        //println!("{:#?}", matches);
+        assert_eq!(matches.len(), 2);
+        assert!(contains_entry(&matches, "a0"));
+        assert!(contains_entry(&matches, "a7"));
+        // check priority
+        assert_eq!(matches[0].name.as_str(), "a0");
+    }
+
+    fn lpm(name: &str, addr: &str, len: u8) -> TableEntry<1, ()> {
+        let addr: IpAddr = addr.parse().unwrap();
+        TableEntry::<1, ()> {
+            key: [Key::Lpm(Prefix { addr, len })],
+            priority: 1,
+            name: name.into(),
+            action: (),
+            action_id: String::new(),
+            parameter_data: Vec::new(),
+        }
+    }
+
+    #[test]
+    /// A few tests on the following table.
+    ///
+    /// +--------+--------------------------+
+    /// | Action | Prefix                   |
+    /// +--------+--------------------------+
+    /// | a0     | fd00:4700::/24           |
+    /// | a1     | fd00:4701::/32           |
+    /// | a2     | fd00:4702::/32           |
+    /// | a3     | fd00:4701:0001::/48      |
+    /// | a4     | fd00:4701:0002::/48      |
+    /// | a5     | fd00:4702:0001::/48      |
+    /// | a6     | fd00:4702:0002::/48      |
+    /// | a7     | fd00:4701:0001:0001::/64 |
+    /// | a8     | fd00:4701:0001:0002::/64 |
+    /// | a9     | fd00:4702:0001:0001::/64 |
+    /// | a10    | fd00:4702:0001:0002::/64 |
+    /// | a11    | fd00:4701:0002:0001::/64 |
+    /// | a12    | fd00:4701:0002:0002::/64 |
+    /// | a13    | fd00:4702:0002:0001::/64 |
+    /// | a14    | fd00:4702:0002:0002::/64 |
+    /// | a15    | fd00:1701::/32           |
+    /// +--------+----------------+---------+
+    fn match_lpm_1() {
+        let mut table = Table::<1, ()>::new();
+        table.entries.insert(lpm("a0", "fd00:4700::", 24));
+        table.entries.insert(lpm("a1", "fd00:4701::", 32));
+        table.entries.insert(lpm("a2", "fd00:4702::", 32));
+        table.entries.insert(lpm("a3", "fd00:4701:0001::", 48));
+        table.entries.insert(lpm("a4", "fd00:4701:0002::", 48));
+        table.entries.insert(lpm("a5", "fd00:4702:0001::", 48));
+        table.entries.insert(lpm("a6", "fd00:4702:0002::", 48));
+        table.entries.insert(lpm("a7", "fd00:4701:0001:0001::", 64));
+        table.entries.insert(lpm("a8", "fd00:4701:0001:0002::", 64));
+        table.entries.insert(lpm("a9", "fd00:4702:0001:0001::", 64));
+        table
+            .entries
+            .insert(lpm("a10", "fd00:4702:0001:0002::", 64));
+        table
+            .entries
+            .insert(lpm("a11", "fd00:4701:0002:0001::", 64));
+        table
+            .entries
+            .insert(lpm("a12", "fd00:4701:0002:0002::", 64));
+        table
+            .entries
+            .insert(lpm("a13", "fd00:4702:0002:0001::", 64));
+        table
+            .entries
+            .insert(lpm("a14", "fd00:4702:0002:0002::", 64));
+        table.entries.insert(lpm("a15", "fd00:1701::", 32));
+
+        let addr: Ipv6Addr = "fd00:4700::1".parse().unwrap();
+        let selector = [BigUint::from(u128::from_be_bytes(addr.octets()))];
+        let matches = table.match_selector(&selector);
+        //println!("{:#?}", matches);
+        assert_eq!(matches.len(), 1);
+        assert!(contains_entry(&matches, "a0"));
+
+        let addr: Ipv6Addr = "fd00:4800::1".parse().unwrap();
+        let selector = [BigUint::from(u128::from_be_bytes(addr.octets()))];
+        let matches = table.match_selector(&selector);
+        assert_eq!(matches.len(), 0);
+        //println!("{:#?}", matches);
+
+        let addr: Ipv6Addr = "fd00:4702:0002:0002::1".parse().unwrap();
+        let selector = [BigUint::from(u128::from_be_bytes(addr.octets()))];
+        let matches = table.match_selector(&selector);
+        //println!("{:#?}", matches);
+        assert_eq!(matches.len(), 1); // only one longest prefix match
+        assert!(contains_entry(&matches, "a14"));
+        // longest prefix first
+        assert_eq!(matches[0].name.as_str(), "a14");
+    }
+
+    fn tlpm(
+        name: &str,
+        addr: &str,
+        len: u8,
+        zone: Ternary,
+        priority: u32,
+    ) -> TableEntry<2, ()> {
+        TableEntry::<2, ()> {
+            key: [
+                Key::Lpm(Prefix {
+                    addr: addr.parse().unwrap(),
+                    len,
+                }),
+                Key::Ternary(zone),
+            ],
+            priority,
+            name: name.into(),
+            action: (),
+            action_id: String::new(),
+            parameter_data: Vec::new(),
+        }
+    }
+
+    #[test]
+    fn match_lpm_ternary_1() {
+        let table = Table::<2, ()> {
+            entries: HashSet::from([
+                tlpm("a0", "fd00:1::", 64, Ternary::DontCare, 1),
+                tlpm(
+                    "a1",
+                    "fd00:1::",
+                    64,
+                    Ternary::Value(BigUintKey {
+                        value: 1u16.into(),
+                        width: 2,
+                    }),
+                    10,
+                ),
+                tlpm(
+                    "a2",
+                    "fd00:1::",
+                    64,
+                    Ternary::Value(BigUintKey {
+                        value: 2u16.into(),
+                        width: 2,
+                    }),
+                    10,
+                ),
+                tlpm(
+                    "a3",
+                    "fd00:1::",
+                    64,
+                    Ternary::Value(BigUintKey {
+                        value: 3u16.into(),
+                        width: 2,
+                    }),
+                    10,
+                ),
+            ]),
+        };
+
+        let dst: Ipv6Addr = "fd00:1::1".parse().unwrap();
+        let selector = [
+            BigUint::from(u128::from_le_bytes(dst.octets())),
+            BigUint::from(0u16),
+        ];
+        let matches = table.match_selector(&selector);
+        println!("zone-0: {:#?}", matches);
+        let selector = [
+            BigUint::from(u128::from_le_bytes(dst.octets())),
+            BigUint::from(2u16),
+        ];
+        let matches = table.match_selector(&selector);
+        println!("zone-2: {:#?}", matches);
+    }
+
+    fn lpre(
+        name: &str,
+        addr: &str,
+        len: u8,
+        zone: Ternary,
+        range: (u32, u32),
+        tag: u64,
+        priority: u32,
+    ) -> TableEntry<4, ()> {
+        TableEntry::<4, ()> {
+            key: [
+                Key::Lpm(Prefix {
+                    addr: addr.parse().unwrap(),
+                    len,
+                }),
+                Key::Ternary(zone),
+                Key::Range(
+                    BigUintKey {
+                        value: range.0.into(),
+                        width: 4,
+                    },
+                    BigUintKey {
+                        value: range.1.into(),
+                        width: 4,
+                    },
+                ),
+                Key::Exact(BigUintKey {
+                    value: tag.into(),
+                    width: 8,
+                }),
+            ],
+            priority,
+            name: name.into(),
+            action: (),
+            action_id: String::new(),
+            parameter_data: Vec::new(),
+        }
+    }
+
+    struct ActionData {
+        value: u64,
+    }
+
+    #[test]
+    fn match_lpm_ternary_range() {
+        let table = Table::<4, ()> {
+            entries: HashSet::from([
+                lpre("a0", "fd00:1::", 64, Ternary::DontCare, (80, 80), 100, 1),
+                lpre(
+                    "a1",
+                    "fd00:1::",
+                    64,
+                    Ternary::DontCare,
+                    (443, 443),
+                    100,
+                    1,
+                ),
+                lpre("a2", "fd00:1::", 64, Ternary::DontCare, (80, 80), 200, 1),
+                lpre(
+                    "a3",
+                    "fd00:1::",
+                    64,
+                    Ternary::DontCare,
+                    (443, 443),
+                    200,
+                    1,
+                ),
+                lpre(
+                    "a4",
+                    "fd00:1::",
+                    64,
+                    Ternary::Value(BigUintKey {
+                        value: 99u16.into(),
+                        width: 2,
+                    }),
+                    (443, 443),
+                    200,
+                    10,
+                ),
+            ]),
+        };
+        let dst: Ipv6Addr = "fd00:1::1".parse().unwrap();
+        let selector = [
+            BigUint::from(u128::from_le_bytes(dst.octets())),
+            BigUint::from(0u16),
+            BigUint::from(80u32),
+            BigUint::from(100u64),
+        ];
+        let matches = table.match_selector(&selector);
+        println!("m1: {:#?}", matches);
+
+        let selector = [
+            BigUint::from(u128::from_le_bytes(dst.octets())),
+            BigUint::from(0u16),
+            BigUint::from(443u32),
+            BigUint::from(200u64),
+        ];
+        let matches = table.match_selector(&selector);
+        println!("m2: {:#?}", matches);
+
+        let selector = [
+            BigUint::from(u128::from_le_bytes(dst.octets())),
+            BigUint::from(99u16),
+            BigUint::from(443u32),
+            BigUint::from(200u64),
+        ];
+        let matches = table.match_selector(&selector);
+        println!("m3: {:#?}", matches);
+
+        let selector = [
+            BigUint::from(u128::from_le_bytes(dst.octets())),
+            BigUint::from(99u16),
+            BigUint::from(80u32),
+            BigUint::from(200u64),
+        ];
+        let matches = table.match_selector(&selector);
+        println!("m4: {:#?}", matches);
+    }
+
+    #[test]
+    fn match_with_action() {
+        let mut data = ActionData { value: 47 };
+
+        let table = Table::<1, Arc<dyn Fn(&mut ActionData)>> {
+            entries: HashSet::from([
+                TableEntry::<1, Arc<dyn Fn(&mut ActionData)>> {
+                    key: [Key::Exact(BigUintKey {
+                        value: 1u8.into(),
+                        width: 1,
+                    })],
+                    priority: 0,
+                    name: "a0".into(),
+                    action: Arc::new(|a: &mut ActionData| {
+                        a.value += 10;
+                    }),
+                    action_id: String::new(),
+                    parameter_data: Vec::new(),
+                },
+                TableEntry::<1, Arc<dyn Fn(&mut ActionData)>> {
+                    key: [Key::Exact(BigUintKey {
+                        value: 2u8.into(),
+                        width: 1,
+                    })],
+                    priority: 0,
+                    name: "a1".into(),
+                    action: Arc::new(|a: &mut ActionData| {
+                        a.value -= 10;
+                    }),
+                    action_id: String::new(),
+                    parameter_data: Vec::new(),
+                },
+            ]),
+        };
+
+        let selector = [BigUint::from(1u8)];
+        let matches = table.match_selector(&selector);
+        println!("m4: {:#?}", matches);
+        assert_eq!(matches.len(), 1);
+        (matches[0].action)(&mut data);
+        assert_eq!(data.value, 57);
+    }
+}
+
\ No newline at end of file diff --git a/src/sidecar_lite/lib.rs.html b/src/sidecar_lite/lib.rs.html new file mode 100644 index 00000000..aba34e6c --- /dev/null +++ b/src/sidecar_lite/lib.rs.html @@ -0,0 +1,13 @@ +lib.rs - source +
1
+2
+3
+4
+5
+
// Copyright 2022 Oxide Computer Company
+
+#![allow(clippy::too_many_arguments)]
+
+p4_macro::use_p4!(p4 = "test/src/p4/sidecar-lite.p4", pipeline_name = "main");
+
\ No newline at end of file diff --git a/src/tests/data.rs.html b/src/tests/data.rs.html new file mode 100644 index 00000000..f2decd63 --- /dev/null +++ b/src/tests/data.rs.html @@ -0,0 +1,29 @@ +data.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+
#[macro_export]
+macro_rules! muffins {
+    () => {
+        (
+            b"do you know the muffin man?",
+            b"the muffin man?",
+            b"the muffin man!",
+            b"why yes",
+            b"i know the muffin man",
+            b"the muffin man is me!!!",
+        )
+    };
+}
+
\ No newline at end of file diff --git a/src/tests/lib.rs.html b/src/tests/lib.rs.html new file mode 100644 index 00000000..2e75860f --- /dev/null +++ b/src/tests/lib.rs.html @@ -0,0 +1,59 @@ +lib.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+
#[cfg(test)]
+mod basic_router;
+#[cfg(test)]
+mod controller_multiple_instantiation;
+#[cfg(test)]
+mod decap;
+#[cfg(test)]
+mod disag_router;
+#[cfg(test)]
+mod dload;
+#[cfg(test)]
+mod dynamic_router;
+#[cfg(test)]
+mod headers;
+#[cfg(test)]
+mod hub;
+#[cfg(test)]
+mod mac_rewrite;
+#[cfg(test)]
+mod range;
+#[cfg(test)]
+mod table_in_egress_and_ingress;
+#[cfg(test)]
+mod vlan;
+
+pub mod data;
+pub mod packet;
+pub mod softnpu;
+
\ No newline at end of file diff --git a/src/tests/packet.rs.html b/src/tests/packet.rs.html new file mode 100644 index 00000000..eb109a21 --- /dev/null +++ b/src/tests/packet.rs.html @@ -0,0 +1,73 @@ +packet.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+
use pnet::packet::ipv4::MutableIpv4Packet;
+use pnet::packet::ipv6::MutableIpv6Packet;
+use std::net::{Ipv4Addr, Ipv6Addr};
+
+pub fn v6<'a>(
+    src: Ipv6Addr,
+    dst: Ipv6Addr,
+    payload: &[u8],
+    data: &'a mut [u8],
+) -> MutableIpv6Packet<'a> {
+    data.fill(0);
+
+    let mut pkt = MutableIpv6Packet::new(data).unwrap();
+    pkt.set_source(src);
+    pkt.set_destination(dst);
+    pkt.set_payload_length(payload.len() as u16);
+    pkt.set_payload(payload);
+    pkt
+}
+
+pub fn v4<'a>(
+    src: Ipv4Addr,
+    dst: Ipv4Addr,
+    payload: &[u8],
+    data: &'a mut [u8],
+) -> MutableIpv4Packet<'a> {
+    data.fill(0);
+
+    let mut pkt = MutableIpv4Packet::new(data).unwrap();
+    pkt.set_source(src);
+    pkt.set_destination(dst);
+    pkt.set_total_length(20 + payload.len() as u16);
+    pkt.set_payload(payload);
+    pkt
+}
+
\ No newline at end of file diff --git a/src/tests/softnpu.rs.html b/src/tests/softnpu.rs.html new file mode 100644 index 00000000..383399aa --- /dev/null +++ b/src/tests/softnpu.rs.html @@ -0,0 +1,1059 @@ +softnpu.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+
use crate::packet;
+use colored::Colorize;
+use p4rs::packet_in;
+use rand::Rng;
+use std::net::{Ipv4Addr, Ipv6Addr};
+use std::sync::atomic::{AtomicUsize, Ordering};
+use std::sync::Arc;
+use std::thread::spawn;
+use xfr::{ring, FrameBuffer, RingConsumer, RingProducer};
+
+pub fn do_expect_frames(
+    name: &str,
+    phy: &Arc<OuterPhy<RING, FBUF, MTU>>,
+    expected: &[RxFrame],
+    dmac: Option<[u8; 6]>,
+) {
+    let n = expected.len();
+    let mut frames = Vec::new();
+    loop {
+        let fs = phy.recv();
+        frames.extend_from_slice(&fs);
+        // TODO this is not a great interface, if frames.len() > n, we should do
+        // something besides hang forever.
+        if frames.len() == n {
+            break;
+        }
+    }
+    for i in 0..n {
+        let payload = match frames[i].ethertype {
+            0x0901 => {
+                let mut payload = &frames[i].payload[..];
+                let et = u16::from_be_bytes([payload[5], payload[6]]);
+                payload = &payload[23..];
+                if et == 0x86dd {
+                    payload = &payload[40..];
+                }
+                if et == 0x0800 {
+                    payload = &payload[20..];
+                }
+                payload
+            }
+            0x86dd => &frames[i].payload[40..],
+            0x0800 => &frames[i].payload[20..],
+            _ => &frames[i].payload[..],
+        };
+        let m = String::from_utf8_lossy(payload).to_string();
+        println!("[{}] {}", name.magenta(), m.dimmed());
+        assert_eq!(frames[i].src, expected[i].src, "src");
+        if let Some(d) = dmac {
+            assert_eq!(frames[i].dst, d, "dst");
+        }
+        assert_eq!(frames[i].ethertype, expected[i].ethertype, "ethertype");
+        assert_eq!(payload, expected[i].payload, "payload");
+    }
+}
+
+#[macro_export]
+macro_rules! expect_frames {
+    ($phy:expr, $expected:expr) => {
+        $crate::softnpu::do_expect_frames(
+            stringify!($phy),
+            &$phy,
+            $expected,
+            None,
+        )
+    };
+    ($phy:expr, $expected:expr, $dmac:expr) => {
+        $crate::softnpu::do_expect_frames(
+            stringify!($phy),
+            &$phy,
+            $expected,
+            Some($dmac),
+        )
+    };
+}
+
+const RING: usize = 1024;
+const FBUF: usize = 4096;
+const MTU: usize = 1500;
+
+pub struct SoftNpu<P: p4rs::Pipeline> {
+    pub pipeline: Option<P>,
+    inner_phys: Option<Vec<InnerPhy<RING, FBUF, MTU>>>,
+    outer_phys: Vec<Arc<OuterPhy<RING, FBUF, MTU>>>,
+    _fb: Arc<FrameBuffer<FBUF, MTU>>,
+}
+
+impl<P: p4rs::Pipeline + 'static> SoftNpu<P> {
+    /// Create a new SoftNpu ASIC emulator. The `radix` indicates the number of
+    /// ports. The `pipeline` is the `x4c` compiled program that the ASIC will
+    /// run. When `cpu_port` is set to true, sidecar data in `TxFrame` elements
+    /// will be added to packets sent through port 0 (as a sidecar header) on
+    /// the way to the ASIC.
+    pub fn new(radix: usize, pipeline: P, cpu_port: bool) -> Self {
+        let fb = Arc::new(FrameBuffer::<FBUF, MTU>::new());
+        let mut inner_phys = Vec::new();
+        let mut outer_phys = Vec::new();
+        for i in 0..radix {
+            let (rx_p, rx_c) = ring::<RING, FBUF, MTU>(fb.clone());
+            let (tx_p, tx_c) = ring::<RING, FBUF, MTU>(fb.clone());
+            let inner_phy = InnerPhy::new(i, rx_c, tx_p);
+            let mut outer_phy = OuterPhy::new(i, rx_p, tx_c);
+            inner_phys.push(inner_phy);
+            if i == 0 && cpu_port {
+                outer_phy.sidecar_encap = true;
+            }
+            outer_phys.push(Arc::new(outer_phy));
+        }
+        let inner_phys = Some(inner_phys);
+        SoftNpu {
+            inner_phys,
+            outer_phys,
+            _fb: fb,
+            pipeline: Some(pipeline),
+        }
+    }
+
+    pub fn run(&mut self) {
+        let inner_phys = match self.inner_phys.take() {
+            Some(phys) => phys,
+            None => panic!("phys already in use"),
+        };
+        let pipe = match self.pipeline.take() {
+            Some(pipe) => pipe,
+            None => panic!("pipe already in use"),
+        };
+        spawn(move || {
+            Self::do_run(inner_phys, pipe);
+        });
+    }
+
+    fn do_run(inner_phys: Vec<InnerPhy<RING, FBUF, MTU>>, mut pipeline: P) {
+        loop {
+            // TODO: yes this is a highly suboptimal linear gather-scatter across
+            // each ingress. Will update to something more concurrent eventually.
+            for (i, ig) in inner_phys.iter().enumerate() {
+                // keep track of how many frames we've produced for each egress
+                let mut egress_count = vec![0; inner_phys.len()];
+
+                // keep track of how many frames we've consumed for this ingress
+                let mut frames_in = 0;
+
+                for fp in ig.rx_c.consumable() {
+                    frames_in += 1;
+                    let content = ig.rx_c.read_mut(fp);
+
+                    let mut pkt = packet_in::new(content);
+
+                    let port = i as u16;
+                    let output = pipeline.process_packet(port, &mut pkt);
+                    for (out_pkt, out_port) in &output {
+                        let out_port = *out_port as usize;
+                        //
+                        // get frame for packet
+                        //
+
+                        let phy = &inner_phys[out_port];
+                        let eg = &phy.tx_p;
+                        let mut fps = eg.reserve(1).unwrap();
+                        let fp = fps.next().unwrap();
+
+                        //
+                        // emit headers
+                        //
+
+                        eg.write_at(fp, out_pkt.header_data.as_slice(), 0);
+
+                        //
+                        // emit payload
+                        //
+
+                        eg.write_at(
+                            fp,
+                            out_pkt.payload_data,
+                            out_pkt.header_data.len(),
+                        );
+
+                        egress_count[out_port] += 1;
+                    }
+                }
+                ig.rx_c.consume(frames_in).unwrap();
+                ig.rx_counter.fetch_add(frames_in, Ordering::Relaxed);
+
+                for (j, n) in egress_count.iter().enumerate() {
+                    if *n == 0 {
+                        continue;
+                    }
+                    let phy = &inner_phys[j];
+                    phy.tx_p.produce(*n).unwrap();
+                    phy.tx_counter.fetch_add(*n, Ordering::Relaxed);
+                }
+            }
+        }
+    }
+
+    pub fn phy(&self, i: usize) -> Arc<OuterPhy<RING, FBUF, MTU>> {
+        self.outer_phys[i].clone()
+    }
+}
+
+pub struct InnerPhy<const R: usize, const N: usize, const F: usize> {
+    pub index: usize,
+    rx_c: RingConsumer<R, N, F>,
+    tx_p: RingProducer<R, N, F>,
+    tx_counter: AtomicUsize,
+    rx_counter: AtomicUsize,
+}
+
+pub struct OuterPhy<const R: usize, const N: usize, const F: usize> {
+    pub index: usize,
+    pub mac: [u8; 6],
+    rx_p: RingProducer<R, N, F>,
+    tx_c: RingConsumer<R, N, F>,
+    tx_counter: AtomicUsize,
+    rx_counter: AtomicUsize,
+    sidecar_encap: bool,
+}
+
+unsafe impl<const R: usize, const N: usize, const F: usize> Send
+    for OuterPhy<R, N, F>
+{
+}
+
+unsafe impl<const R: usize, const N: usize, const F: usize> Sync
+    for OuterPhy<R, N, F>
+{
+}
+
+pub struct Interface6<const R: usize, const N: usize, const F: usize> {
+    pub phy: Arc<OuterPhy<R, N, F>>,
+    pub addr: Ipv6Addr,
+    pub sc_egress: u16,
+}
+
+impl<const R: usize, const N: usize, const F: usize> Interface6<R, N, F> {
+    pub fn new(phy: Arc<OuterPhy<R, N, F>>, addr: Ipv6Addr) -> Self {
+        Self {
+            phy,
+            addr,
+            sc_egress: 0,
+        }
+    }
+
+    pub fn send(
+        &self,
+        mac: [u8; 6],
+        ip: Ipv6Addr,
+        payload: &[u8],
+    ) -> Result<(), anyhow::Error> {
+        let n = 40 + payload.len();
+        let mut buf = [0u8; F];
+        packet::v6(self.addr, ip, payload, &mut buf);
+        let mut txf = TxFrame::new(mac, 0x86dd, &buf[..n]);
+        txf.sc_egress = self.sc_egress;
+        self.phy.send(&[txf])?;
+        Ok(())
+    }
+}
+
+pub struct Interface4<const R: usize, const N: usize, const F: usize> {
+    pub phy: Arc<OuterPhy<R, N, F>>,
+    pub addr: Ipv4Addr,
+    pub sc_egress: u16,
+}
+
+impl<const R: usize, const N: usize, const F: usize> Interface4<R, N, F> {
+    pub fn new(phy: Arc<OuterPhy<R, N, F>>, addr: Ipv4Addr) -> Self {
+        Self {
+            phy,
+            addr,
+            sc_egress: 0,
+        }
+    }
+
+    pub fn send(
+        &self,
+        mac: [u8; 6],
+        ip: Ipv4Addr,
+        payload: &[u8],
+    ) -> Result<(), anyhow::Error> {
+        let n = 20 + payload.len();
+        let mut buf = [0u8; F];
+        packet::v4(self.addr, ip, payload, &mut buf);
+        let mut txf = TxFrame::new(mac, 0x0800, &buf[..n]);
+        txf.sc_egress = self.sc_egress;
+        self.phy.send(&[txf])?;
+        Ok(())
+    }
+}
+
+pub struct TxFrame<'a> {
+    pub dst: [u8; 6],
+    pub ethertype: u16,
+    pub payload: &'a [u8],
+    pub sc_egress: u16,
+    pub vid: Option<u16>,
+}
+
+pub struct RxFrame<'a> {
+    pub src: [u8; 6],
+    pub ethertype: u16,
+    pub payload: &'a [u8],
+    pub vid: Option<u16>,
+}
+
+impl<'a> RxFrame<'a> {
+    pub fn new(src: [u8; 6], ethertype: u16, payload: &'a [u8]) -> Self {
+        Self {
+            src,
+            ethertype,
+            payload,
+            vid: None,
+        }
+    }
+    pub fn newv(
+        src: [u8; 6],
+        ethertype: u16,
+        payload: &'a [u8],
+        vid: u16,
+    ) -> Self {
+        Self {
+            src,
+            ethertype,
+            payload,
+            vid: Some(vid),
+        }
+    }
+}
+
+impl<'a> TxFrame<'a> {
+    pub fn new(dst: [u8; 6], ethertype: u16, payload: &'a [u8]) -> Self {
+        Self {
+            dst,
+            ethertype,
+            payload,
+            sc_egress: 0,
+            vid: None,
+        }
+    }
+
+    pub fn newv(
+        dst: [u8; 6],
+        ethertype: u16,
+        payload: &'a [u8],
+        vid: u16,
+    ) -> Self {
+        Self {
+            dst,
+            ethertype,
+            payload,
+            sc_egress: 0,
+            vid: Some(vid),
+        }
+    }
+}
+
+#[derive(Clone)]
+pub struct OwnedFrame {
+    pub dst: [u8; 6],
+    pub src: [u8; 6],
+    pub vid: Option<u16>,
+    pub ethertype: u16,
+    pub payload: Vec<u8>,
+}
+
+impl OwnedFrame {
+    pub fn new(
+        dst: [u8; 6],
+        src: [u8; 6],
+        ethertype: u16,
+        vid: Option<u16>,
+        payload: Vec<u8>,
+    ) -> Self {
+        Self {
+            dst,
+            src,
+            vid,
+            ethertype,
+            payload,
+        }
+    }
+}
+
+impl<const R: usize, const N: usize, const F: usize> InnerPhy<R, N, F> {
+    pub fn new(
+        index: usize,
+        rx_c: RingConsumer<R, N, F>,
+        tx_p: RingProducer<R, N, F>,
+    ) -> Self {
+        Self {
+            index,
+            rx_c,
+            tx_p,
+            tx_counter: AtomicUsize::new(0),
+            rx_counter: AtomicUsize::new(0),
+        }
+    }
+}
+
+impl<const R: usize, const N: usize, const F: usize> OuterPhy<R, N, F> {
+    pub fn new(
+        index: usize,
+        rx_p: RingProducer<R, N, F>,
+        tx_c: RingConsumer<R, N, F>,
+    ) -> Self {
+        let mut rng = rand::thread_rng();
+        let m = rng.gen_range::<u32, _>(0xf00000..0xffffff).to_le_bytes();
+        let mac = [0xa8, 0x40, 0x25, m[0], m[1], m[2]];
+
+        Self {
+            index,
+            rx_p,
+            tx_c,
+            mac,
+            tx_counter: AtomicUsize::new(0),
+            rx_counter: AtomicUsize::new(0),
+            sidecar_encap: false,
+        }
+    }
+
+    pub fn send(&self, frames: &[TxFrame<'_>]) -> Result<(), xfr::Error> {
+        let n = frames.len();
+        let fps = self.rx_p.reserve(n)?;
+        for (i, fp) in fps.enumerate() {
+            let f = &frames[i];
+            self.rx_p.write_at(fp, f.dst.as_slice(), 0);
+            self.rx_p.write_at(fp, &self.mac, 6);
+            let mut off = 12;
+            if self.sidecar_encap {
+                self.rx_p
+                    .write_at(fp, 0x0901u16.to_be_bytes().as_slice(), off);
+                off += 2;
+                // sc_code = SC_FWD_FROM_USERSPACE
+                self.rx_p.write_at(fp, &[0u8], off);
+                off += 1;
+                // sc_ingress
+                let ingress = f.sc_egress;
+                self.rx_p
+                    .write_at(fp, ingress.to_be_bytes().as_slice(), off);
+                off += 2;
+                // sc_egress
+                let egress = f.sc_egress;
+                self.rx_p.write_at(fp, egress.to_be_bytes().as_slice(), off);
+                off += 2;
+                // sc_ether_type
+                self.rx_p.write_at(
+                    fp,
+                    f.ethertype.to_be_bytes().as_slice(),
+                    off,
+                );
+                off += 2;
+                // sc_payload
+                self.rx_p.write_at(fp, [0u8; 16].as_slice(), off);
+                off += 16;
+            } else if let Some(vid) = f.vid {
+                self.rx_p
+                    .write_at(fp, 0x8100u16.to_be_bytes().as_slice(), off);
+                off += 2;
+                self.rx_p.write_at(fp, vid.to_be_bytes().as_slice(), off);
+                off += 2;
+                self.rx_p.write_at(
+                    fp,
+                    f.ethertype.to_be_bytes().as_slice(),
+                    off,
+                );
+                off += 2;
+            } else {
+                self.rx_p.write_at(
+                    fp,
+                    f.ethertype.to_be_bytes().as_slice(),
+                    off,
+                );
+                off += 2;
+            }
+
+            self.rx_p.write_at(fp, f.payload, off);
+        }
+        self.rx_p.produce(n)?;
+        self.tx_counter.fetch_add(n, Ordering::Relaxed);
+        Ok(())
+    }
+
+    pub fn recv(&self) -> Vec<OwnedFrame> {
+        let mut buf = Vec::new();
+        loop {
+            for fp in self.tx_c.consumable() {
+                let b = self.tx_c.read(fp);
+                let mut et = u16::from_be_bytes([b[12], b[13]]);
+                let mut vid: Option<u16> = None;
+                let payload = if et == 0x8100 {
+                    let v = u16::from_be_bytes([b[14], b[15]]);
+                    et = u16::from_be_bytes([b[16], b[17]]);
+                    vid = Some(v);
+                    b[18..].to_vec()
+                } else {
+                    b[14..].to_vec()
+                };
+                let frame = OwnedFrame::new(
+                    b[0..6].try_into().unwrap(),
+                    b[6..12].try_into().unwrap(),
+                    et,
+                    vid,
+                    payload,
+                );
+                buf.push(frame);
+            }
+            if !buf.is_empty() {
+                break;
+            }
+        }
+        self.tx_c.consume(buf.len()).unwrap();
+        self.rx_counter.fetch_add(buf.len(), Ordering::Relaxed);
+
+        buf
+    }
+
+    pub fn recv_buffer_len(&self) -> usize {
+        self.tx_c.consumable().count()
+    }
+
+    pub fn tx_count(&self) -> usize {
+        self.tx_counter.load(Ordering::Relaxed)
+    }
+
+    pub fn rx_count(&self) -> usize {
+        self.rx_counter.load(Ordering::Relaxed)
+    }
+}
+
\ No newline at end of file diff --git a/src/vlan_switch/vlan-switch.rs.html b/src/vlan_switch/vlan-switch.rs.html new file mode 100644 index 00000000..2d5119f0 --- /dev/null +++ b/src/vlan_switch/vlan-switch.rs.html @@ -0,0 +1,143 @@ +vlan-switch.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+
#![allow(clippy::needless_update)]
+use tests::expect_frames;
+use tests::softnpu::{RxFrame, SoftNpu, TxFrame};
+
+p4_macro::use_p4!(
+    p4 = "book/code/src/bin/vlan-switch.p4",
+    pipeline_name = "vlan_switch"
+);
+
+fn main() -> Result<(), anyhow::Error> {
+    let mut pipeline = main_pipeline::new(2);
+
+    let m1 = [0x33, 0x33, 0x33, 0x33, 0x33, 0x33];
+    let m2 = [0x44, 0x44, 0x44, 0x44, 0x44, 0x44];
+    let m3 = [0x55, 0x55, 0x55, 0x55, 0x55, 0x55];
+
+    init_tables(&mut pipeline, m1, m2);
+    run_test(pipeline, m2, m3)
+}
+
+fn init_tables(pipeline: &mut main_pipeline, m1: [u8; 6], m2: [u8; 6]) {
+    // add static forwarding entries
+    pipeline.add_ingress_fwd_fib_entry("forward", &m1, &0u16.to_be_bytes(), 0);
+    pipeline.add_ingress_fwd_fib_entry("forward", &m2, &1u16.to_be_bytes(), 0);
+
+    // port 0 vlan 47
+    pipeline.add_ingress_vlan_port_vlan_entry(
+        "filter",
+        0u16.to_be_bytes().as_ref(),
+        47u16.to_be_bytes().as_ref(),
+        0,
+    );
+
+    // sanity check the table
+    let x = pipeline.get_ingress_vlan_port_vlan_entries();
+    println!("{:#?}", x);
+
+    // port 1 vlan 47
+    pipeline.add_ingress_vlan_port_vlan_entry(
+        "filter",
+        1u16.to_be_bytes().as_ref(),
+        47u16.to_be_bytes().as_ref(),
+        0,
+    );
+}
+
+fn run_test(
+    pipeline: main_pipeline,
+    m2: [u8; 6],
+    m3: [u8; 6],
+) -> Result<(), anyhow::Error> {
+    // create and run the softnpu instance
+    let mut npu = SoftNpu::new(2, pipeline, false);
+    let phy1 = npu.phy(0);
+    let phy2 = npu.phy(1);
+    npu.run();
+
+    // send a packet we expect to make it through
+    phy1.send(&[TxFrame::newv(m2, 0, b"blueberry", 47)])?;
+    expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b"blueberry", 47)]);
+
+    // send 3 packets, we expect the first 2 to get filtered by vlan rules
+    phy1.send(&[TxFrame::newv(m2, 0, b"poppyseed", 74)])?; // 74 != 47
+    phy1.send(&[TxFrame::new(m2, 0, b"banana")])?; // no tag
+    phy1.send(&[TxFrame::newv(m2, 0, b"muffin", 47)])?;
+    phy1.send(&[TxFrame::newv(m3, 0, b"nut", 47)])?; // no forwarding entry
+    expect_frames!(phy2, &[RxFrame::newv(phy1.mac, 0x8100, b"muffin", 47)]);
+
+    Ok(())
+}
+
\ No newline at end of file diff --git a/src/x4c/lib.rs.html b/src/x4c/lib.rs.html new file mode 100644 index 00000000..d4fde7e5 --- /dev/null +++ b/src/x4c/lib.rs.html @@ -0,0 +1,239 @@ +lib.rs - source +
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+
// Copyright 2022 Oxide Computer Company
+
+use anyhow::{anyhow, Result};
+use clap::Parser;
+use p4::check::Diagnostics;
+use p4::{
+    ast::AST, check, error, error::SemanticError, lexer, parser, preprocessor,
+};
+use std::fs;
+use std::path::Path;
+use std::sync::Arc;
+
+#[derive(Parser)]
+#[clap(version = "0.1")]
+pub struct Opts {
+    /// Show parsed lexical tokens.
+    #[clap(long)]
+    pub show_tokens: bool,
+
+    /// Show parsed abstract syntax tree.
+    #[clap(long)]
+    pub show_ast: bool,
+
+    /// Show parsed preprocessor info.
+    #[clap(long)]
+    pub show_pre: bool,
+
+    /// Show high-level intermediate representation info.
+    #[clap(long)]
+    pub show_hlir: bool,
+
+    /// File to compile.
+    pub filename: String,
+
+    /// What target to generate code for.
+    #[clap(arg_enum, default_value_t = Target::Rust)]
+    pub target: Target,
+
+    /// Just check code, do not compile.
+    #[clap(long)]
+    pub check: bool,
+
+    /// Filename to write generated code to.
+    #[clap(short, long, default_value = "out.rs")]
+    pub out: String,
+}
+
+#[derive(clap::ArgEnum, Clone)]
+pub enum Target {
+    Rust,
+    RedHawk,
+    Docs,
+}
+
+pub fn process_file(
+    filename: Arc<String>,
+    ast: &mut AST,
+    opts: &Opts,
+) -> Result<()> {
+    let contents = fs::read_to_string(&*filename)
+        .map_err(|e| anyhow!("read input: {}: {}", &*filename, e))?;
+
+    let ppr = preprocessor::run(&contents, filename.clone())?;
+    if opts.show_pre {
+        println!("{:#?}", ppr.elements);
+    }
+
+    for included in &ppr.elements.includes {
+        let path = Path::new(included);
+        if !path.is_absolute() {
+            let parent = Path::new(&*filename).parent().unwrap();
+            let joined = parent.join(included);
+            process_file(
+                Arc::new(joined.to_str().unwrap().to_string()),
+                ast,
+                opts,
+            )?
+        } else {
+            process_file(Arc::new(included.clone()), ast, opts)?
+        }
+    }
+
+    let lines: Vec<&str> = ppr.lines.iter().map(|x| x.as_str()).collect();
+
+    let mut lxr = lexer::Lexer::new(lines.clone(), filename);
+    lxr.show_tokens = opts.show_tokens;
+
+    let mut psr = parser::Parser::new(lxr);
+    psr.run(ast)?;
+    if opts.show_ast {
+        println!("{:#?}", ast);
+    }
+
+    let (hlir, diags) = check::all(ast);
+    check(&lines, &diags)?;
+
+    if opts.show_hlir {
+        println!("{:#?}", hlir);
+    }
+
+    Ok(())
+}
+
+fn check(lines: &[&str], diagnostics: &Diagnostics) -> Result<()> {
+    let errors = diagnostics.errors();
+    if !errors.is_empty() {
+        let mut err = Vec::new();
+        for e in errors {
+            err.push(SemanticError {
+                at: e.token.clone(),
+                message: e.message.clone(),
+                source: lines[e.token.line].into(),
+            });
+        }
+        Err(error::Error::Semantic(err))?;
+    }
+    Ok(())
+}
+
\ No newline at end of file diff --git a/src/x4c_error_codes/lib.rs.html b/src/x4c_error_codes/lib.rs.html new file mode 100644 index 00000000..413779a1 --- /dev/null +++ b/src/x4c_error_codes/lib.rs.html @@ -0,0 +1,5 @@ +lib.rs - source +
1
+
//mod error_codes;
+
\ No newline at end of file diff --git a/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 00000000..1447df79 --- /dev/null +++ b/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 00000000..d7e9c149 --- /dev/null +++ b/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 00000000..7a1e5fc5 Binary files /dev/null and b/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 00000000..e766e06c Binary files /dev/null and b/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 00000000..16fe87b0 --- /dev/null +++ b/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 00000000..31aa7938 --- /dev/null +++ b/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 00000000..1866ad4b Binary files /dev/null and b/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 00000000..4b3edc29 --- /dev/null +++ b/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 00000000..462c34ef Binary files /dev/null and b/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 00000000..0d2941e1 --- /dev/null +++ b/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 00000000..10b558e0 Binary files /dev/null and b/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 00000000..5ec64eef Binary files /dev/null and b/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 00000000..181a07f6 Binary files /dev/null and b/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 00000000..2ae08a7b Binary files /dev/null and b/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 00000000..175fa4f4 --- /dev/null +++ b/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 00000000..0263fc30 Binary files /dev/null and b/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/static.files/clipboard-7571035ce49a181d.svg b/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 00000000..8adbd996 --- /dev/null +++ b/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/static.files/favicon-16x16-8b506e7a72182f1c.png b/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 00000000..ea4b45ca Binary files /dev/null and b/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/static.files/favicon-2c020d218678b618.svg b/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 00000000..8b34b511 --- /dev/null +++ b/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/static.files/favicon-32x32-422f7d1d52889060.png b/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 00000000..69b8613c Binary files /dev/null and b/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/static.files/main-48f368f3872407c8.js b/static.files/main-48f368f3872407c8.js new file mode 100644 index 00000000..987fae42 --- /dev/null +++ b/static.files/main-48f368f3872407c8.js @@ -0,0 +1,11 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function blurHandler(event,parentElem,hideCallback){if(!parentElem.contains(document.activeElement)&&!parentElem.contains(event.relatedTarget)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileTopbar=document.querySelector(".mobile-topbar");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileTopbar){const mobileTitle=document.createElement("h2");mobileTitle.className="location";if(hasClass(document.querySelector(".rustdoc"),"crate")){mobileTitle.innerText=`Crate ${window.currentCrate}`}else if(locationTitle){mobileTitle.innerHTML=locationTitle.innerHTML}mobileTopbar.appendChild(mobileTitle)}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadScript(getVar("static-root-path")+getVar("settings-js"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=").map(x=>x.replace(/\+/g," "));params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}if(savedHash.startsWith("impl-")){const splitAt=savedHash.indexOf("/");if(splitAt!==-1){const implId=savedHash.slice(0,splitAt);const assocId=savedHash.slice(splitAt+1);const implElem=document.getElementById(implId);if(implElem&&implElem.parentElement.tagName==="SUMMARY"&&implElem.parentElement.parentElement.tagName==="DETAILS"){onEachLazy(implElem.parentElement.parentElement.querySelectorAll(`[id^="${assocId}"]`),item=>{const numbered=/([^-]+)-([0-9]+)/.exec(item.id);if(item.id===assocId||(numbered&&numbered[1]===assocId)){openParentDetails(item);item.scrollIntoView();setTimeout(()=>{window.location.replace("#"+item.id)},0)}})}}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const modpath=hasClass(document.querySelector(".rustdoc"),"mod")?"../":"";const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=`${modpath}${name}/index.html`}else{path=`${modpath}${shortty}.${name}.html`}let current_page=document.location.href.toString();if(current_page.endsWith("/")){current_page+="index.html"}const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Aliases");block("union","unions","Unions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("opaque","opaque-types","Opaque Types");block("attr","attributes","Attribute Macros");block("derive","derives","Derive Macros");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}window.register_type_impls=imp=>{if(!imp||!imp[window.currentCrate]){return}window.pending_type_impls=null;const idMap=new Map();let implementations=document.getElementById("implementations-list");let trait_implementations=document.getElementById("trait-implementations-list");let trait_implementations_header=document.getElementById("trait-implementations");const script=document.querySelector("script[data-self-path]");const selfPath=script?script.getAttribute("data-self-path"):null;const mainContent=document.querySelector("#main-content");const sidebarSection=document.querySelector(".sidebar section");let methods=document.querySelector(".sidebar .block.method");let associatedTypes=document.querySelector(".sidebar .block.associatedtype");let associatedConstants=document.querySelector(".sidebar .block.associatedconstant");let sidebarTraitList=document.querySelector(".sidebar .block.trait-implementation");for(const impList of imp[window.currentCrate]){const types=impList.slice(2);const text=impList[0];const isTrait=impList[1]!==0;const traitName=impList[1];if(types.indexOf(selfPath)===-1){continue}let outputList=isTrait?trait_implementations:implementations;if(outputList===null){const outputListName=isTrait?"Trait Implementations":"Implementations";const outputListId=isTrait?"trait-implementations-list":"implementations-list";const outputListHeaderId=isTrait?"trait-implementations":"implementations";const outputListHeader=document.createElement("h2");outputListHeader.id=outputListHeaderId;outputListHeader.innerText=outputListName;outputList=document.createElement("div");outputList.id=outputListId;if(isTrait){const link=document.createElement("a");link.href=`#${outputListHeaderId}`;link.innerText="Trait Implementations";const h=document.createElement("h3");h.appendChild(link);trait_implementations=outputList;trait_implementations_header=outputListHeader;sidebarSection.appendChild(h);sidebarTraitList=document.createElement("ul");sidebarTraitList.className="block trait-implementation";sidebarSection.appendChild(sidebarTraitList);mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}else{implementations=outputList;if(trait_implementations){mainContent.insertBefore(outputListHeader,trait_implementations_header);mainContent.insertBefore(outputList,trait_implementations_header)}else{const mainContent=document.querySelector("#main-content");mainContent.appendChild(outputListHeader);mainContent.appendChild(outputList)}}}const template=document.createElement("template");template.innerHTML=text;onEachLazy(template.content.querySelectorAll("a"),elem=>{const href=elem.getAttribute("href");if(href&&!href.startsWith("#")&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});onEachLazy(template.content.querySelectorAll("[id]"),el=>{let i=0;if(idMap.has(el.id)){i=idMap.get(el.id)}else if(document.getElementById(el.id)){i=1;while(document.getElementById(`${el.id}-${2 * i}`)){i=2*i}while(document.getElementById(`${el.id}-${i}`)){i+=1}}if(i!==0){const oldHref=`#${el.id}`;const newHref=`#${el.id}-${i}`;el.id=`${el.id}-${i}`;onEachLazy(template.content.querySelectorAll("a[href]"),link=>{if(link.getAttribute("href")===oldHref){link.href=newHref}})}idMap.set(el.id,i+1)});const templateAssocItems=template.content.querySelectorAll("section.tymethod, "+"section.method, section.associatedtype, section.associatedconstant");if(isTrait){const li=document.createElement("li");const a=document.createElement("a");a.href=`#${template.content.querySelector(".impl").id}`;a.textContent=traitName;li.appendChild(a);sidebarTraitList.append(li)}else{onEachLazy(templateAssocItems,item=>{let block=hasClass(item,"associatedtype")?associatedTypes:(hasClass(item,"associatedconstant")?associatedConstants:(methods));if(!block){const blockTitle=hasClass(item,"associatedtype")?"Associated Types":(hasClass(item,"associatedconstant")?"Associated Constants":("Methods"));const blockClass=hasClass(item,"associatedtype")?"associatedtype":(hasClass(item,"associatedconstant")?"associatedconstant":("method"));const blockHeader=document.createElement("h3");const blockLink=document.createElement("a");blockLink.href="#implementations";blockLink.innerText=blockTitle;blockHeader.appendChild(blockLink);block=document.createElement("ul");block.className=`block ${blockClass}`;const insertionReference=methods||sidebarTraitList;if(insertionReference){const insertionReferenceH=insertionReference.previousElementSibling;sidebarSection.insertBefore(blockHeader,insertionReferenceH);sidebarSection.insertBefore(block,insertionReferenceH)}else{sidebarSection.appendChild(blockHeader);sidebarSection.appendChild(block)}if(hasClass(item,"associatedtype")){associatedTypes=block}else if(hasClass(item,"associatedconstant")){associatedConstants=block}else{methods=block}}const li=document.createElement("li");const a=document.createElement("a");a.innerText=item.id.split("-")[0].split(".")[1];a.href=`#${item.id}`;li.appendChild(a);block.appendChild(li)})}outputList.appendChild(template.content)}for(const list of[methods,associatedTypes,associatedConstants,sidebarTraitList]){if(!list){continue}const newChildren=Array.prototype.slice.call(list.children);newChildren.sort((a,b)=>{const aI=a.innerText;const bI=b.innerText;return aIbI?1:0});list.replaceChildren(...newChildren)}};if(window.pending_type_impls){window.register_type_impls(window.pending_type_impls)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";link.textContent=crate;const li=document.createElement("li");if(window.rootPath!=="./"&&crate===window.currentCrate){li.className="current"}li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!e.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.contains(event.relatedTarget)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(document.activeElement)&&!window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.contains(event.relatedTarget)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=()=>{e.TOOLTIP_FORCE_VISIBLE=e.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!e.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(e);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointermove=ev=>{if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(e,true)};e.onpointerleave=ev=>{if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&window.CURRENT_TOOLTIP_ELEMENT&&!window.CURRENT_TOOLTIP_ELEMENT.contains(ev.relatedTarget)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=switchFocus=>{hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=()=>{onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){const SIDEBAR_MIN=100;const SIDEBAR_MAX=500;const RUSTDOC_MOBILE_BREAKPOINT=700;const BODY_MIN=400;const SIDEBAR_VANISH_THRESHOLD=SIDEBAR_MIN/2;const sidebarButton=document.getElementById("sidebar-button");if(sidebarButton){sidebarButton.addEventListener("click",e=>{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false");if(document.querySelector(".rustdoc.src")){window.rustdocToggleSrcSidebar()}e.preventDefault()})}let currentPointerId=null;let desiredSidebarSize=null;let pendingSidebarResizingFrame=false;const resizer=document.querySelector(".sidebar-resizer");const sidebar=document.querySelector(".sidebar");if(!resizer||!sidebar){return}const isSrcPage=hasClass(document.body,"src");function hideSidebar(){if(isSrcPage){window.rustdocCloseSourceSidebar();updateLocalStorage("src-sidebar-width",null);document.documentElement.style.removeProperty("--src-sidebar-width");sidebar.style.removeProperty("--src-sidebar-width");resizer.style.removeProperty("--src-sidebar-width")}else{addClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","true");updateLocalStorage("desktop-sidebar-width",null);document.documentElement.style.removeProperty("--desktop-sidebar-width");sidebar.style.removeProperty("--desktop-sidebar-width");resizer.style.removeProperty("--desktop-sidebar-width")}}function showSidebar(){if(isSrcPage){window.rustdocShowSourceSidebar()}else{removeClass(document.documentElement,"hide-sidebar");updateLocalStorage("hide-sidebar","false")}}function changeSidebarSize(size){if(isSrcPage){updateLocalStorage("src-sidebar-width",size);sidebar.style.setProperty("--src-sidebar-width",size+"px");resizer.style.setProperty("--src-sidebar-width",size+"px")}else{updateLocalStorage("desktop-sidebar-width",size);sidebar.style.setProperty("--desktop-sidebar-width",size+"px");resizer.style.setProperty("--desktop-sidebar-width",size+"px")}}function isSidebarHidden(){return isSrcPage?!hasClass(document.documentElement,"src-sidebar-expanded"):hasClass(document.documentElement,"hide-sidebar")}function resize(e){if(currentPointerId===null||currentPointerId!==e.pointerId){return}e.preventDefault();const pos=e.clientX-3;if(pos=SIDEBAR_MIN){if(isSidebarHidden()){showSidebar()}const constrainedPos=Math.min(pos,window.innerWidth-BODY_MIN,SIDEBAR_MAX);changeSidebarSize(constrainedPos);desiredSidebarSize=constrainedPos;if(pendingSidebarResizingFrame!==false){clearTimeout(pendingSidebarResizingFrame)}pendingSidebarResizingFrame=setTimeout(()=>{if(currentPointerId===null||pendingSidebarResizingFrame===false){return}pendingSidebarResizingFrame=false;document.documentElement.style.setProperty("--resizing-sidebar-width",desiredSidebarSize+"px")},100)}}window.addEventListener("resize",()=>{if(window.innerWidth=(window.innerWidth-BODY_MIN)){changeSidebarSize(window.innerWidth-BODY_MIN)}else if(desiredSidebarSize!==null&&desiredSidebarSize>SIDEBAR_MIN){changeSidebarSize(desiredSidebarSize)}});function stopResize(e){if(currentPointerId===null){return}if(e){e.preventDefault()}desiredSidebarSize=sidebar.getBoundingClientRect().width;removeClass(resizer,"active");window.removeEventListener("pointermove",resize,false);window.removeEventListener("pointerup",stopResize,false);removeClass(document.documentElement,"sidebar-resizing");document.documentElement.style.removeProperty("--resizing-sidebar-width");if(resizer.releasePointerCapture){resizer.releasePointerCapture(currentPointerId);currentPointerId=null}}function initResize(e){if(currentPointerId!==null||e.altKey||e.ctrlKey||e.metaKey||e.button!==0){return}if(resizer.setPointerCapture){resizer.setPointerCapture(e.pointerId);if(!resizer.hasPointerCapture(e.pointerId)){resizer.releasePointerCapture(e.pointerId);return}currentPointerId=e.pointerId}window.hideAllModals(false);e.preventDefault();window.addEventListener("pointermove",resize,false);window.addEventListener("pointercancel",stopResize,false);window.addEventListener("pointerup",stopResize,false);addClass(resizer,"active");addClass(document.documentElement,"sidebar-resizing");const pos=e.clientX-sidebar.offsetLeft-3;document.documentElement.style.setProperty("--resizing-sidebar-width",pos+"px");desiredSidebarSize=null}resizer.addEventListener("pointerdown",initResize,false)}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/static.files/normalize-76eba96aa4d2e634.css b/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 00000000..469959f1 --- /dev/null +++ b/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/static.files/noscript-04d5337699b92874.css b/static.files/noscript-04d5337699b92874.css new file mode 100644 index 00000000..fbd55f57 --- /dev/null +++ b/static.files/noscript-04d5337699b92874.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path,#sidebar-button,.sidebar-resizer{display:none !important;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;}:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}@media (prefers-color-scheme:dark){:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}} \ No newline at end of file diff --git a/static.files/rust-logo-151179464ae7ed46.svg b/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 00000000..62424d8f --- /dev/null +++ b/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/static.files/rustdoc-5bc39a1768837dd0.css b/static.files/rustdoc-5bc39a1768837dd0.css new file mode 100644 index 00000000..175164ef --- /dev/null +++ b/static.files/rustdoc-5bc39a1768837dd0.css @@ -0,0 +1,24 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;--desktop-sidebar-width:200px;--src-sidebar-width:300px;--desktop-sidebar-z-index:100;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p,.docblock>.warning{margin:0 0 .75em 0;}p:last-child,.docblock>.warning:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.logo-container{line-height:0;display:block;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 var(--desktop-sidebar-width);width:var(--desktop-sidebar-width);overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;z-index:var(--desktop-sidebar-z-index);}.rustdoc.src .sidebar{flex-basis:50px;width:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;}.hide-sidebar .sidebar,.hide-sidebar .sidebar-resizer{display:none;}.sidebar-resizer{touch-action:none;width:9px;cursor:col-resize;z-index:calc(var(--desktop-sidebar-z-index) + 1);position:fixed;height:100%;left:calc(var(--desktop-sidebar-width) + 1px);}.rustdoc.src .sidebar-resizer{left:49px;}.src-sidebar-expanded .src .sidebar-resizer{left:var(--src-sidebar-width);}.sidebar-resizing{-moz-user-select:none;-webkit-user-select:none;-ms-user-select:none;user-select:none;}.sidebar-resizing*{cursor:col-resize !important;}.sidebar-resizing .sidebar{position:fixed;}.sidebar-resizing>body{padding-left:var(--resizing-sidebar-width);}.sidebar-resizer:hover,.sidebar-resizer:active,.sidebar-resizer:focus,.sidebar-resizer.active{width:10px;margin:0;left:var(--desktop-sidebar-width);border-left:solid 1px var(--sidebar-resizer-hover);}.src-sidebar-expanded .rustdoc.src .sidebar-resizer:hover,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:active,.src-sidebar-expanded .rustdoc.src .sidebar-resizer:focus,.src-sidebar-expanded .rustdoc.src .sidebar-resizer.active{left:calc(var(--src-sidebar-width) - 1px);}@media (pointer:coarse){.sidebar-resizer{display:none !important;}}.sidebar-resizer.active{padding:0 140px;width:2px;margin-left:-140px;border-left:none;}.sidebar-resizer.active:before{border-left:solid 2px var(--sidebar-resizer-active);display:block;height:100%;content:"";}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}.src .sidebar>*{visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:var(--src-sidebar-width);width:var(--src-sidebar-width);}.src-sidebar-expanded .src .sidebar>*{visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.logo-container>img{height:48px;width:48px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;margin-right:0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>.version,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar .current a,.sidebar-crate a.logo-container:hover+h2 a,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.sidebar-crate{display:flex;align-items:center;justify-content:center;margin:14px 32px 1rem;row-gap:10px;column-gap:32px;flex-wrap:wrap;}.sidebar-crate h2{flex-grow:1;margin:0 -8px;align-self:start;}.sidebar-crate .logo-container{margin:0 -16px 0 -16px;text-align:center;}.sidebar-crate h2 a{display:block;margin:0 calc(-24px + 0.25rem) 0 -0.2rem;padding:calc((16px - 0.57rem ) / 2 ) 0.25rem;padding-left:0.2rem;}.sidebar-crate h2 .version{display:block;font-weight:normal;font-size:1rem;overflow-wrap:break-word;}.sidebar-crate+.version{margin-top:-1rem;margin-bottom:1rem;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}div.where{white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.section-header{display:block;position:relative;}.section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.section-header>.anchor{left:-15px;padding-right:8px;}h2.section-header>.anchor{padding-right:6px;}a.doc-anchor{color:var(--main-color);display:none;position:absolute;left:-17px;padding-right:5px;padding-left:3px;}*:hover>.doc-anchor{display:block;}.top-doc>.docblock>*:first-child>.doc-anchor{display:none !important;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover:not(.doc-anchor),.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block li.current a{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:calc(var(--desktop-sidebar-z-index) + 1);margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{display:block;padding:3px;margin-bottom:5px;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;vertical-align:baseline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji,.item-info .stab::before{font-size:1.25rem;}.stab .emoji{margin-right:0.3rem;}.item-info .stab::before{content:"\0";width:0;display:inline-block;color:transparent;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}.content .docblock .warning{border-left:2px solid var(--warning-border-color);padding:14px;position:relative;overflow-x:visible !important;}.content .docblock .warning::before{color:var(--warning-border-color);content:"ⓘ";position:absolute;left:-25px;top:5px;font-weight:bold;font-size:1.25rem;}.top-doc>.docblock>.warning:first-child::before{top:20px;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;font-variant-numeric:tabular-nums;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}.src-sidebar-title{position:sticky;top:0;display:flex;padding:8px 8px 0 48px;margin-bottom:7px;background:var(--sidebar-background-color);border-bottom:1px solid var(--border-color);}#settings-menu,#help-button{margin-left:4px;display:flex;}#sidebar-button{display:none;line-height:0;}.hide-sidebar #sidebar-button,.src #sidebar-button{display:flex;margin-right:4px;position:fixed;left:6px;height:34px;width:34px;background-color:var(--main-background-color);z-index:1;}.src #sidebar-button{left:8px;z-index:calc(var(--desktop-sidebar-z-index) + 1);}.hide-sidebar .src #sidebar-button{position:static;}#settings-menu>a,#help-button>a,#sidebar-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus,#sidebar-button>a:hover,#sidebar-button>a:focus{border-color:var(--settings-button-border-focus);}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}.src #sidebar-button>a:before,.sidebar-menu-toggle:before{content:url('data:image/svg+xml,\ + ');opacity:0.75;}.sidebar-menu-toggle:hover:before,.sidebar-menu-toggle:active:before,.sidebar-menu-toggle:focus:before{opacity:1;}.src #sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');opacity:0.75;}@media (max-width:850px){#search-tabs .count{display:block;}}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location,.sidebar-resizer{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.src .search-form{margin-left:40px;}.hide-sidebar .search-form{margin-left:32px;}.hide-sidebar .src .search-form{margin-left:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.hide-sidebar .mobile-topbar{display:none;}.sidebar-menu-toggle{width:45px;border:none;line-height:0;}.hide-sidebar .sidebar-menu-toggle{display:none;}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#copy-path,#help-button{display:none;}#sidebar-button>a:before{content:url('data:image/svg+xml,\ + \ + \ + ');width:22px;height:22px;}.sidebar-menu-toggle:before{filter:var(--mobile-sidebar-menu-filter);}.sidebar-menu-toggle:hover{background:var(--main-background-color);}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{position:fixed;max-width:100vw;width:100vw;}.src .src-sidebar-title{padding-top:0;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;}:root[data-theme="light"]{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#f5f5f5;--sidebar-background-color-hover:#e0e0e0;--code-block-background-color:#f5f5f5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--mobile-sidebar-menu-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#fff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#f5f5f5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);--sidebar-resizer-hover:hsl(207,90%,66%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="dark"]{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:#4e8bca;--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2a2a2a;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);--sidebar-resizer-hover:hsl(207,30%,54%);--sidebar-resizer-active:hsl(207,90%,54%);}:root[data-theme="ayu"]{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--mobile-sidebar-menu-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--warning-border-color:#ff8e00;--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:#5b3b01;--scrape-example-code-line-highlight-focus:#7c4b0f;--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);--sidebar-resizer-hover:hsl(34,50%,33%);--sidebar-resizer-active:hsl(34,100%,66%);}:root[data-theme="ayu"] h1,:root[data-theme="ayu"] h2,:root[data-theme="ayu"] h3,:root[data-theme="ayu"] h4,:where(:root[data-theme="ayu"]) h1 a,:root[data-theme="ayu"] .sidebar h2 a,:root[data-theme="ayu"] .sidebar h3 a{color:#fff;}:root[data-theme="ayu"] .docblock code{color:#ffb454;}:root[data-theme="ayu"] .docblock a>code{color:#39AFD7 !important;}:root[data-theme="ayu"] .code-header,:root[data-theme="ayu"] .docblock pre>code,:root[data-theme="ayu"] pre,:root[data-theme="ayu"] pre>code,:root[data-theme="ayu"] .item-info code,:root[data-theme="ayu"] .rustdoc.source .example-wrap{color:#e6e1cf;}:root[data-theme="ayu"] .sidebar .current,:root[data-theme="ayu"] .sidebar .current a,:root[data-theme="ayu"] .sidebar a:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:hover,:root[data-theme="ayu"] details.dir-entry summary:hover,:root[data-theme="ayu"] #src-sidebar div.files>a:focus,:root[data-theme="ayu"] details.dir-entry summary:focus,:root[data-theme="ayu"] #src-sidebar div.files>a.selected{color:#ffb44c;}:root[data-theme="ayu"] .sidebar-elems .location{color:#ff7733;}:root[data-theme="ayu"] .src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}:root[data-theme="ayu"] .search-results a:hover,:root[data-theme="ayu"] .search-results a:focus{color:#fff !important;background-color:#3c3c3c;}:root[data-theme="ayu"] .search-results a{color:#0096cf;}:root[data-theme="ayu"] .search-results a div.desc{color:#c5c5c5;}:root[data-theme="ayu"] .result-name .primitive>i,:root[data-theme="ayu"] .result-name .keyword>i{color:#788797;}:root[data-theme="ayu"] #search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}:root[data-theme="ayu"] #search-tabs>button:not(.selected){border:none;background-color:transparent !important;}:root[data-theme="ayu"] #search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}:root[data-theme="ayu"] #settings-menu>a img,:root[data-theme="ayu"] #sidebar-button>a:before{filter:invert(100);} \ No newline at end of file diff --git a/static.files/scrape-examples-ef1e698c1d417c0c.js b/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 00000000..ba830e37 --- /dev/null +++ b/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/static.files/search-dd67cee4cfa65049.js b/static.files/search-dd67cee4cfa65049.js new file mode 100644 index 00000000..ef8bf865 --- /dev/null +++ b/static.files/search-dd67cee4cfa65049.js @@ -0,0 +1,5 @@ +"use strict";if(!Array.prototype.toSpliced){Array.prototype.toSpliced=function(){const me=this.slice();Array.prototype.splice.apply(me,arguments);return me}}(function(){const itemTypes=["keyword","primitive","mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","associatedtype","constant","associatedconstant","union","foreigntype","existential","attr","derive","traitalias","generic",];const longItemTypes=["keyword","primitive type","module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","assoc type","constant","assoc const","union","foreign type","existential type","attribute macro","derive macro","trait alias",];const TY_GENERIC=itemTypes.indexOf("generic");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let functionTypeFingerprint;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;let typeNameIdOfTuple;let typeNameIdOfUnit;let typeNameIdOfTupleOrUnit;function buildTypeMapIndex(name,isAssocType){if(name===""||name===null){return null}if(typeNameIdMap.has(name)){const obj=typeNameIdMap.get(name);obj.assocOnly=isAssocType&&obj.assocOnly;return obj.id}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,{id,assocOnly:isAssocType});return id}}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return"=,>-])".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","||c==="="}function isPathSeparator(c){return c===":"||c===" "}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(c!==" "){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}const bindingName=parserState.isInBinding;parserState.isInBinding=null;return{name:"never",id:null,fullPath:["never"],pathWithoutLast:[],pathLast:"never",normalizedPathLast:"never",generics:[],bindings:new Map(),typeFilter:"primitive",bindingName,}}const quadcolon=/::\s*::/.exec(path);if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(quadcolon!==null){throw["Unexpected ",quadcolon[0]]}const pathSegments=path.split(/(?:::\s*)|(?:\s+(?:::\s*)?)/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}const bindingName=parserState.isInBinding;parserState.isInBinding=null;const bindings=new Map();const pathLast=pathSegments[pathSegments.length-1];return{name:name.trim(),id:null,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast,normalizedPathLast:pathLast.replace(/_/g,""),generics:generics.filter(gen=>{if(gen.bindingName!==null){bindings.set(gen.bindingName.name,[gen,...gen.bindingName.generics]);return false}return true}),bindings,typeFilter,bindingName,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}else{throw["Unexpected ",c]}}parserState.pos+=1;end=parserState.pos}if(foundExclamation!==-1&&foundExclamation!==start&&isIdentCharacter(parserState.userQuery[foundExclamation-1])){if(parserState.typeFilter===null){parserState.typeFilter="macro"}else if(parserState.typeFilter!=="macro"){throw["Invalid search type: macro ","!"," and ",parserState.typeFilter," both specified",]}end=foundExclamation}return end}function getNextElem(query,parserState,elems,isInGenerics){const generics=[];skipWhitespace(parserState);let start=parserState.pos;let end;if("[(".indexOf(parserState.userQuery[parserState.pos])!==-1){let endChar=")";let name="()";let friendlyName="tuple";if(parserState.userQuery[parserState.pos]==="["){endChar="]";name="[]";friendlyName="slice"}parserState.pos+=1;const{foundSeparator}=getItemsBefore(query,parserState,generics,endChar);const typeFilter=parserState.typeFilter;const isInBinding=parserState.isInBinding;if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive ",name," and ",typeFilter," both specified",]}parserState.typeFilter=null;parserState.isInBinding=null;for(const gen of generics){if(gen.bindingName!==null){throw["Type parameter ","=",` cannot be within ${friendlyName} `,name]}}if(name==="()"&&!foundSeparator&&generics.length===1&&typeFilter===null){elems.push(generics[0])}else{parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}elems.push({name:name,id:null,fullPath:[name],pathWithoutLast:[],pathLast:name,normalizedPathLast:name,generics,bindings:new Map(),typeFilter:"primitive",bindingName:isInBinding,})}}else{const isStringElem=parserState.userQuery[start]==="\"";if(isStringElem){start+=1;getStringElem(query,parserState,isInGenerics);end=parserState.pos-1}else{end=getIdentEndPosition(parserState)}if(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}if(parserState.userQuery[parserState.pos]==="="){if(parserState.isInBinding){throw["Cannot write ","="," twice in a binding"]}if(!isInGenerics){throw["Type parameter ","="," must be within generics list"]}const name=parserState.userQuery.slice(start,end).trim();if(name==="!"){throw["Type parameter ","="," key cannot be ","!"," never type"]}if(name.includes("!")){throw["Type parameter ","="," key cannot be ","!"," macro"]}if(name.includes("::")){throw["Type parameter ","="," key cannot contain ","::"," path"]}if(name.includes(":")){throw["Type parameter ","="," key cannot contain ",":"," type"]}parserState.isInBinding={name,generics}}else{elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let foundSeparator=false;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;const oldIsInBinding=parserState.isInBinding;parserState.isInBinding=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===")"){extra="("}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",",",", ","=",", or ",endChar,...extra,", found ",c,]}throw["Expected ",","," or ","=",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter;parserState.isInBinding=oldIsInBinding;return{foundSeparator}}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}else if(parserState.pos>0){throw["Unexpected ",c," after ",parserState.userQuery[parserState.pos-1]]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(c===" "){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,totalElems:0,literalSearch:false,error:null,correction:null,proposeCorrectionFrom:null,proposeCorrectionTo:null,typeFingerprint:new Uint32Array(4),}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&rawSearchIndex.has(elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}for(const constraints of elem.bindings.values()){for(const constraint of constraints){convertTypeFilterOnElem(constraint)}}}userQuery=userQuery.trim().replace(/\r|\n|\t/g," ");const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,isInBinding:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;query.totalElems=parserState.totalElems;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id!==-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.item=searchIndex[result.id];result.word=searchIndex[result.id].word;result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});return transformResults(result_list)}function unifyFunctionTypes(fnTypesIn,queryElems,whereClause,mgensIn,solutionCb){const mgens=mgensIn===null?null:new Map(mgensIn);if(queryElems.length===0){return!solutionCb||solutionCb(mgens)}if(!fnTypesIn||fnTypesIn.length===0){return false}const ql=queryElems.length;const fl=fnTypesIn.length;if(ql===1&&queryElems[0].generics.length===0&&queryElems[0].bindings.size===0){const queryElem=queryElems[0];for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){continue}if(fnType.id<0&&queryElem.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==queryElem.id){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,queryElem.id);if(!solutionCb||solutionCb(mgensScratch)){return true}}else if(!solutionCb||solutionCb(mgens?new Map(mgens):null)){return true}}for(const fnType of fnTypesIn){if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){continue}if(fnType.id<0){if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){continue}const mgensScratch=new Map(mgens);mgensScratch.set(fnType.id,0);if(unifyFunctionTypes(whereClause[(-fnType.id)-1],queryElems,whereClause,mgensScratch,solutionCb)){return true}}else if(unifyFunctionTypes([...fnType.generics,...Array.from(fnType.bindings.values()).flat()],queryElems,whereClause,mgens?new Map(mgens):null,solutionCb)){return true}}return false}const fnTypes=fnTypesIn.slice();const flast=fl-1;const qlast=ql-1;const queryElem=queryElems[qlast];let queryElemsTmp=null;for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgens)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==queryElem.id){continue}mgensScratch.set(fnType.id,queryElem.id)}else{mgensScratch=mgens}fnTypes[i]=fnTypes[flast];fnTypes.length=flast;if(!queryElemsTmp){queryElemsTmp=queryElems.slice(0,qlast)}const passesUnification=unifyFunctionTypes(fnTypes,queryElemsTmp,whereClause,mgensScratch,mgensScratch=>{if(fnType.generics.length===0&&queryElem.generics.length===0&&fnType.bindings.size===0&&queryElem.bindings.size===0){return!solutionCb||solutionCb(mgensScratch)}const solution=unifyFunctionTypeCheckBindings(fnType,queryElem,whereClause,mgensScratch);if(!solution){return false}const simplifiedGenerics=solution.simplifiedGenerics;for(const simplifiedMgens of solution.mgens){const passesUnification=unifyFunctionTypes(simplifiedGenerics,queryElem.generics,whereClause,simplifiedMgens,solutionCb);if(passesUnification){return true}}return false});if(passesUnification){return true}fnTypes[flast]=fnTypes[i];fnTypes[i]=fnType;fnTypes.length=fl}for(let i=flast;i>=0;i-=1){const fnType=fnTypes[i];if(!unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens)){continue}let mgensScratch;if(fnType.id<0){mgensScratch=new Map(mgens);if(mgensScratch.has(fnType.id)&&mgensScratch.get(fnType.id)!==0){continue}mgensScratch.set(fnType.id,0)}else{mgensScratch=mgens}const generics=fnType.id<0?whereClause[(-fnType.id)-1]:fnType.generics;const bindings=fnType.bindings?Array.from(fnType.bindings.values()).flat():[];const passesUnification=unifyFunctionTypes(fnTypes.toSpliced(i,1,...generics,...bindings),queryElems,whereClause,mgensScratch,solutionCb);if(passesUnification){return true}}return false}function unifyFunctionTypeIsMatchCandidate(fnType,queryElem,whereClause,mgensIn){if(!typePassesFilter(queryElem.typeFilter,fnType.ty)){return false}if(fnType.id<0&&queryElem.id<0){if(mgensIn){if(mgensIn.has(fnType.id)&&mgensIn.get(fnType.id)!==queryElem.id){return false}for(const[fid,qid]of mgensIn.entries()){if(fnType.id!==fid&&queryElem.id===qid){return false}if(fnType.id===fid&&queryElem.id!==qid){return false}}}return true}else{if(queryElem.id===typeNameIdOfArrayOrSlice&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)){}else if(queryElem.id===typeNameIdOfTupleOrUnit&&(fnType.id===typeNameIdOfTuple||fnType.id===typeNameIdOfUnit)){}else if(fnType.id!==queryElem.id||queryElem.id===null){return false}if((fnType.generics.length+fnType.bindings.size)===0&&queryElem.generics.length!==0){return false}if(fnType.bindings.size0){const fnTypePath=fnType.path!==undefined&&fnType.path!==null?fnType.path.split("::"):[];if(queryElemPathLength>fnTypePath.length){return false}let i=0;for(const path of fnTypePath){if(path===queryElem.pathWithoutLast[i]){i+=1;if(i>=queryElemPathLength){break}}}if(i0){let mgensSolutionSet=[mgensIn];for(const[name,constraints]of queryElem.bindings.entries()){if(mgensSolutionSet.length===0){return false}if(!fnType.bindings.has(name)){return false}const fnTypeBindings=fnType.bindings.get(name);mgensSolutionSet=mgensSolutionSet.flatMap(mgens=>{const newSolutions=[];unifyFunctionTypes(fnTypeBindings,constraints,whereClause,mgens,newMgens=>{newSolutions.push(newMgens);return false});return newSolutions})}if(mgensSolutionSet.length===0){return false}const binds=Array.from(fnType.bindings.entries()).flatMap(entry=>{const[name,constraints]=entry;if(queryElem.bindings.has(name)){return[]}else{return constraints}});if(simplifiedGenerics.length>0){simplifiedGenerics=[...simplifiedGenerics,...binds]}else{simplifiedGenerics=binds}return{simplifiedGenerics,mgens:mgensSolutionSet}}return{simplifiedGenerics,mgens:[mgensIn]}}function unifyFunctionTypeIsUnboxCandidate(fnType,queryElem,whereClause,mgens){if(fnType.id<0&&queryElem.id>=0){if(!whereClause){return false}if(mgens&&mgens.has(fnType.id)&&mgens.get(fnType.id)!==0){return false}const mgensTmp=new Map(mgens);mgensTmp.set(fnType.id,null);return checkIfInList(whereClause[(-fnType.id)-1],queryElem,whereClause,mgensTmp)}else if(fnType.generics.length>0||fnType.bindings.size>0){const simplifiedGenerics=[...fnType.generics,...Array.from(fnType.bindings.values()).flat(),];return checkIfInList(simplifiedGenerics,queryElem,whereClause,mgens)}return false}function checkIfInList(list,elem,whereClause,mgens){for(const entry of list){if(checkType(entry,elem,whereClause,mgens)){return true}}return false}function checkType(row,elem,whereClause,mgens){if(row.bindings.size===0&&elem.bindings.size===0){if(elem.id<0){return row.id<0||checkIfInList(row.generics,elem,whereClause,mgens)}if(row.id>0&&elem.id>0&&elem.pathWithoutLast.length===0&&typePassesFilter(elem.typeFilter,row.ty)&&elem.generics.length===0&&elem.id!==typeNameIdOfArrayOrSlice&&elem.id!==typeNameIdOfTupleOrUnit){return row.id===elem.id||checkIfInList(row.generics,elem,whereClause,mgens)}}return unifyFunctionTypes([row],[elem],whereClause,mgens)}function checkPath(contains,ty){if(contains.length===0){return 0}const maxPathEditDistance=Math.floor(contains.reduce((acc,next)=>acc+next.length,0)/3);let ret_dist=maxPathEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;pathiter:for(let i=length-clength;i>=0;i-=1){let dist_total=0;for(let x=0;xmaxPathEditDistance){continue pathiter}dist_total+=dist}}ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}return ret_dist>maxPathEditDistance?null:ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,implDisambiguator:item.implDisambiguator,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){if(dist<=maxEditDistance||index!==-1){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let path_dist=0;const fullId=row.id;const tfpDist=compareTypeFingerprints(fullId,parsedQuery.typeFingerprint);if(tfpDist!==null){const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem,row.type.where_clause);const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem,row.type.where_clause);if(in_args){results_in_args.max_dist=Math.max(results_in_args.max_dist||0,tfpDist);const maxDist=results_in_args.sizenormalizedIndex&&normalizedIndex!==-1)){index=normalizedIndex}if(elem.fullPath.length>1){path_dist=checkPath(elem.pathWithoutLast,row);if(path_dist===null){return}}if(parsedQuery.literalSearch){if(row.word===elem.pathLast){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(row.normalizedName,elem.normalizedPathLast,maxEditDistance);if(index===-1&&dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}const tfpDist=compareTypeFingerprints(row.id,parsedQuery.typeFingerprint);if(tfpDist===null){return}if(results.size>=MAX_RESULTS&&tfpDist>results.max_dist){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems,row.type.where_clause,null,mgens=>{return unifyFunctionTypes(row.type.output,parsedQuery.returned,row.type.where_clause,mgens)})){return}results.max_dist=Math.max(results.max_dist||0,tfpDist);addIntoResults(results,row.id,pos,0,tfpDist,0,Number.MAX_VALUE)}function innerRunQuery(){const queryLen=parsedQuery.elems.reduce((acc,next)=>acc+next.pathLast.length,0)+parsedQuery.returned.reduce((acc,next)=>acc+next.pathLast.length,0);const maxEditDistance=Math.floor(queryLen/3);const genericSymbols=new Map();function convertNameToId(elem,isAssocType){if(typeNameIdMap.has(elem.normalizedPathLast)&&(isAssocType||!typeNameIdMap.get(elem.normalizedPathLast).assocOnly)){elem.id=typeNameIdMap.get(elem.normalizedPathLast).id}else if(!parsedQuery.literalSearch){let match=null;let matchDist=maxEditDistance+1;let matchName="";for(const[name,{id,assocOnly}]of typeNameIdMap){const dist=editDistance(name,elem.normalizedPathLast,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance&&(isAssocType||!assocOnly)){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==null){parsedQuery.correction=matchName}elem.id=match}if((elem.id===null&&parsedQuery.totalElems>1&&elem.typeFilter===-1&&elem.generics.length===0&&elem.bindings.size===0)||elem.typeFilter===TY_GENERIC){if(genericSymbols.has(elem.name)){elem.id=genericSymbols.get(elem.name)}else{elem.id=-(genericSymbols.size+1);genericSymbols.set(elem.name,elem.id)}if(elem.typeFilter===-1&&elem.name.length>=3){const maxPartDistance=Math.floor(elem.name.length/3);let matchDist=maxPartDistance+1;let matchName="";for(const name of typeNameIdMap.keys()){const dist=editDistance(name,elem.name,maxPartDistance);if(dist<=matchDist&&dist<=maxPartDistance){if(dist===matchDist&&matchName>name){continue}matchDist=dist;matchName=name}}if(matchName!==""){parsedQuery.proposeCorrectionFrom=elem.name;parsedQuery.proposeCorrectionTo=matchName}}elem.typeFilter=TY_GENERIC}if(elem.generics.length>0&&elem.typeFilter===TY_GENERIC){parsedQuery.error=["Generic type parameter ",elem.name," does not accept generic parameters",]}for(const elem2 of elem.generics){convertNameToId(elem2)}elem.bindings=new Map(Array.from(elem.bindings.entries()).map(entry=>{const[name,constraints]=entry;if(!typeNameIdMap.has(name)){parsedQuery.error=["Type parameter ",name," does not exist",];return[null,[]]}for(const elem2 of constraints){convertNameToId(elem2)}return[typeNameIdMap.get(name).id,constraints]}))}const fps=new Set();for(const elem of parsedQuery.elems){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}for(const elem of parsedQuery.returned){convertNameToId(elem);buildFunctionTypeFingerprint(elem,parsedQuery.typeFingerprint,fps)}if(parsedQuery.foundElems===1&&parsedQuery.returned.length===0){if(parsedQuery.elems.length===1){const elem=parsedQuery.elems[0];for(let i=0,nSearchIndex=searchIndex.length;i0){const sortQ=(a,b)=>{const ag=a.generics.length===0&&a.bindings.size===0;const bg=b.generics.length===0&&b.bindings.size===0;if(ag!==bg){return ag-bg}const ai=a.id>0;const bi=b.id>0;return ai-bi};parsedQuery.elems.sort(sortQ);parsedQuery.returned.sort(sortQ);for(let i=0,nSearchIndex=searchIndex.length;i");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){const extraClass=display?" active":"";const output=document.createElement("div");if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,array.length]}function makeTabHeader(tabNb,text,nbElems){const fmtNbElems=nbElems<10?`\u{2007}(${nbElems})\u{2007}\u{2007}`:nbElems<100?`\u{2007}(${nbElems})\u{2007}`:`\u{2007}(${nbElems})`;if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";if(rawSearchIndex.size>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}if(results.query.proposeCorrectionFrom!==null){const orig=results.query.proposeCorrectionFrom;const targ=results.query.proposeCorrectionTo;output+="

"+`Type "${orig}" not found and used as generic parameter. `+`Consider searching for "${targ}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(forced){const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){return types.length>0?types.map(type=>buildItemSearchType(type,lowercasePaths)):EMPTY_GENERICS_ARRAY}const EMPTY_BINDINGS_MAP=new Map();const EMPTY_GENERICS_ARRAY=[];let TYPES_POOL=new Map();function buildItemSearchType(type,lowercasePaths,isAssocType){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;const BINDINGS_DATA=2;let pathIndex,generics,bindings;if(typeof type==="number"){pathIndex=type;generics=EMPTY_GENERICS_ARRAY;bindings=EMPTY_BINDINGS_MAP}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths);if(type.length>BINDINGS_DATA&&type[BINDINGS_DATA].length>0){bindings=new Map(type[BINDINGS_DATA].map(binding=>{const[assocType,constraints]=binding;return[buildItemSearchType(assocType,lowercasePaths,true).id,buildItemSearchTypeAll(constraints,lowercasePaths),]}))}else{bindings=EMPTY_BINDINGS_MAP}}let result;if(pathIndex<0){result={id:pathIndex,ty:TY_GENERIC,path:null,generics,bindings,}}else if(pathIndex===0){result={id:null,ty:null,path:null,generics,bindings,}}else{const item=lowercasePaths[pathIndex-1];result={id:buildTypeMapIndex(item.name,isAssocType),ty:item.ty,path:item.path,generics,bindings,}}const cr=TYPES_POOL.get(result.id);if(cr){if(cr.generics.length===result.generics.length&&cr.generics!==result.generics&&cr.generics.every((x,i)=>result.generics[i]===x)){result.generics=cr.generics}if(cr.bindings.size===result.bindings.size&&cr.bindings!==result.bindings){let ok=true;for(const[k,v]of cr.bindings.entries()){const v2=result.bindings.get(v);if(!v2){ok=false;break}if(v!==v2&&v.length===v2.length&&v.every((x,i)=>v2[i]===x)){result.bindings.set(k,v)}else if(v!==v2){ok=false;break}}if(ok){result.bindings=cr.bindings}}if(cr.ty===result.ty&&cr.path===result.path&&cr.bindings===result.bindings&&cr.generics===result.generics&&cr.ty===result.ty){return cr}}TYPES_POOL.set(result.id,result);return result}function buildFunctionSearchType(itemFunctionDecoder,lowercasePaths){const c=itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset);itemFunctionDecoder.offset+=1;const[zero,ua,la,ob,cb]=["0","@","`","{","}"].map(c=>c.charCodeAt(0));if(c===la){return null}if(c>=zero&&c>1];itemFunctionDecoder.offset+=1;return sign?-value:value}const functionSearchType=decodeList();const INPUTS_DATA=0;const OUTPUT_DATA=1;let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){inputs=[buildItemSearchType(functionSearchType[INPUTS_DATA],lowercasePaths)]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){output=[buildItemSearchType(functionSearchType[OUTPUT_DATA],lowercasePaths)]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}const where_clause=[];const l=functionSearchType.length;for(let i=2;i16){itemFunctionDecoder.backrefQueue.pop()}return ret}function buildFunctionTypeFingerprint(type,output,fps){let input=type.id;if(input===typeNameIdOfArray||input===typeNameIdOfSlice){input=typeNameIdOfArrayOrSlice}if(input===typeNameIdOfTuple||input===typeNameIdOfUnit){input=typeNameIdOfTupleOrUnit}const hashint1=k=>{k=(~~k+0x7ed55d16)+(k<<12);k=(k ^ 0xc761c23c)^(k>>>19);k=(~~k+0x165667b1)+(k<<5);k=(~~k+0xd3a2646c)^(k<<9);k=(~~k+0xfd7046c5)+(k<<3);return(k ^ 0xb55a4f09)^(k>>>16)};const hashint2=k=>{k=~k+(k<<15);k ^=k>>>12;k+=k<<2;k ^=k>>>4;k=Math.imul(k,2057);return k ^(k>>16)};if(input!==null){const h0a=hashint1(input);const h0b=hashint2(input);const h1a=~~(h0a+Math.imul(h0b,2));const h1b=~~(h0a+Math.imul(h0b,3));const h2a=~~(h0a+Math.imul(h0b,4));const h2b=~~(h0a+Math.imul(h0b,5));output[0]|=(1<<(h0a%32))|(1<<(h1b%32));output[1]|=(1<<(h1a%32))|(1<<(h2b%32));output[2]|=(1<<(h2a%32))|(1<<(h0b%32));fps.add(input)}for(const g of type.generics){buildFunctionTypeFingerprint(g,output,fps)}const fb={id:null,ty:0,generics:EMPTY_GENERICS_ARRAY,bindings:EMPTY_BINDINGS_MAP,};for(const[k,v]of type.bindings.entries()){fb.id=k;fb.generics=v;buildFunctionTypeFingerprint(fb,output,fps)}output[3]=fps.size}function compareTypeFingerprints(fullId,queryFingerprint){const fh0=functionTypeFingerprint[fullId*4];const fh1=functionTypeFingerprint[(fullId*4)+1];const fh2=functionTypeFingerprint[(fullId*4)+2];const[qh0,qh1,qh2]=queryFingerprint;const[in0,in1,in2]=[fh0&qh0,fh1&qh1,fh2&qh2];if((in0 ^ qh0)||(in1 ^ qh1)||(in2 ^ qh2)){return null}return functionTypeFingerprint[(fullId*4)+3]}function buildIndex(rawSearchIndex){searchIndex=[];typeNameIdMap=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;typeNameIdOfArray=buildTypeMapIndex("array");typeNameIdOfSlice=buildTypeMapIndex("slice");typeNameIdOfTuple=buildTypeMapIndex("tuple");typeNameIdOfUnit=buildTypeMapIndex("unit");typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");typeNameIdOfTupleOrUnit=buildTypeMapIndex("()");for(const crate of rawSearchIndex.values()){id+=crate.t.length+1}functionTypeFingerprint=new Uint32Array((id+1)*4);id=0;for(const[crate,crateCorpus]of rawSearchIndex){const crateRow={crate:crate,ty:3,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,word:crate,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),deprecated:null,implDisambiguator:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionDecoder={string:crateCorpus.f,offset:0,backrefQueue:[],};const deprecatedItems=new Set(crateCorpus.c);const implDisambiguator=new Map(crateCorpus.b);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;let lastPath=itemPaths.get(0);for(let i=0;i2){path=itemPaths.has(elem[2])?itemPaths.get(elem[2]):lastPath;lastPath=path}lowercasePaths.push({ty:ty,name:name.toLowerCase(),path:path});paths[i]={ty:ty,name:name,path:path}}lastPath="";len=itemTypes.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type,id:id,word,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),implDisambiguator:implDisambiguator.has(i)?implDisambiguator.get(i):null,};id+=1;searchIndex.push(row);lastPath=row.path}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!Object.prototype.hasOwnProperty.call(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=itemTypes.length}TYPES_POOL=new Map()}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;e.preventDefault();search()}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(true)}buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch(new Map())}})() \ No newline at end of file diff --git a/static.files/settings-4313503d2e1961c2.js b/static.files/settings-4313503d2e1961c2.js new file mode 100644 index 00000000..ab425fe4 --- /dev/null +++ b/static.files/settings-4313503d2e1961c2.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break;case"hide-sidebar":if(value===true){addClass(document.documentElement,"hide-sidebar")}else{removeClass(document.documentElement,"hide-sidebar")}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=()=>{changeSetting(toggle.id,toggle.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Hide persistent navigation bar","js_name":"hide-sidebar","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display="";onEachLazy(settingsMenu.querySelectorAll("input[type='checkbox']"),el=>{const val=getSettingValue(el.id);const checked=val==="true";if(checked!==el.checked&&val!==null){el.checked=checked}})}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=event=>{event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=event=>{if(settingsMenu.contains(event.target)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/static.files/src-script-e66d777a5a92e9b2.js b/static.files/src-script-e66d777a5a92e9b2.js new file mode 100644 index 00000000..d0aebb85 --- /dev/null +++ b/static.files/src-script-e66d777a5a92e9b2.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth{removeClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","false")};window.rustdocShowSourceSidebar=()=>{addClass(document.documentElement,"src-sidebar-expanded");updateLocalStorage("source-sidebar-show","true")};window.rustdocToggleSrcSidebar=()=>{if(document.documentElement.classList.contains("src-sidebar-expanded")){window.rustdocCloseSourceSidebar()}else{window.rustdocShowSourceSidebar()}};function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;for(const[key,source]of srcIndex){source[NAME_OFFSET]=key;hasFoundFile=createDirEntry(source,sidebar,"",hasFoundFile)}container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}function highlightSrcLines(){const match=window.location.hash.match(/^#?(\d+)(?:-(\d+))?$/);if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",highlightSrcLines);onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/static.files/storage-4c98445ec4002617.js b/static.files/storage-4c98445ec4002617.js new file mode 100644 index 00000000..b378b856 --- /dev/null +++ b/static.files/storage-4c98445ec4002617.js @@ -0,0 +1 @@ +"use strict";const builtinThemes=["light","dark","ayu"];const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func){for(const elem of arr){if(func(elem)){return true}}return false}function onEachLazy(lazyArray,func){return onEach(Array.prototype.slice.call(lazyArray),func)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){const themeNames=getVar("themes").split(",").filter(t=>t);themeNames.push(...builtinThemes);if(themeNames.indexOf(newThemeName)===-1){return}if(saveTheme){updateLocalStorage("theme",newThemeName)}document.documentElement.setAttribute("data-theme",newThemeName);if(builtinThemes.indexOf(newThemeName)!==-1){if(window.currentTheme){window.currentTheme.parentNode.removeChild(window.currentTheme);window.currentTheme=null}}else{const newHref=getVar("root-path")+encodeURIComponent(newThemeName)+getVar("resource-suffix")+".css";if(!window.currentTheme){if(document.readyState==="loading"){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else{window.currentTheme=document.createElement("link");window.currentTheme.rel="stylesheet";window.currentTheme.id="themeStyle";window.currentTheme.href=newHref;document.documentElement.appendChild(window.currentTheme)}}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}if(getSettingValue("hide-sidebar")==="true"){addClass(document.documentElement,"hide-sidebar")}function updateSidebarWidth(){const desktopSidebarWidth=getSettingValue("desktop-sidebar-width");if(desktopSidebarWidth&&desktopSidebarWidth!=="null"){document.documentElement.style.setProperty("--desktop-sidebar-width",desktopSidebarWidth+"px")}const srcSidebarWidth=getSettingValue("src-sidebar-width");if(srcSidebarWidth&&srcSidebarWidth!=="null"){document.documentElement.style.setProperty("--src-sidebar-width",srcSidebarWidth+"px")}}updateSidebarWidth();window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0);setTimeout(updateSidebarWidth,0)}}) \ No newline at end of file diff --git a/static.files/wheel-7b819b6101059cd0.svg b/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 00000000..83c07f63 --- /dev/null +++ b/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/tests/all.html b/tests/all.html new file mode 100644 index 00000000..462cde08 --- /dev/null +++ b/tests/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/tests/data/index.html b/tests/data/index.html new file mode 100644 index 00000000..78b90818 --- /dev/null +++ b/tests/data/index.html @@ -0,0 +1,2 @@ +tests::data - Rust +

Module tests::data

source ·
\ No newline at end of file diff --git a/tests/data/sidebar-items.js b/tests/data/sidebar-items.js new file mode 100644 index 00000000..5244ce01 --- /dev/null +++ b/tests/data/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {}; \ No newline at end of file diff --git a/tests/index.html b/tests/index.html new file mode 100644 index 00000000..0d96297b --- /dev/null +++ b/tests/index.html @@ -0,0 +1,3 @@ +tests - Rust +
\ No newline at end of file diff --git a/tests/macro.expect_frames!.html b/tests/macro.expect_frames!.html new file mode 100644 index 00000000..d25c0ad6 --- /dev/null +++ b/tests/macro.expect_frames!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.expect_frames.html...

+ + + \ No newline at end of file diff --git a/tests/macro.expect_frames.html b/tests/macro.expect_frames.html new file mode 100644 index 00000000..f6b53d15 --- /dev/null +++ b/tests/macro.expect_frames.html @@ -0,0 +1,5 @@ +expect_frames in tests - Rust +

Macro tests::expect_frames

source ·
macro_rules! expect_frames {
+    ($phy:expr, $expected:expr) => { ... };
+    ($phy:expr, $expected:expr, $dmac:expr) => { ... };
+}
\ No newline at end of file diff --git a/tests/macro.muffins!.html b/tests/macro.muffins!.html new file mode 100644 index 00000000..3f468324 --- /dev/null +++ b/tests/macro.muffins!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.muffins.html...

+ + + \ No newline at end of file diff --git a/tests/macro.muffins.html b/tests/macro.muffins.html new file mode 100644 index 00000000..7595984f --- /dev/null +++ b/tests/macro.muffins.html @@ -0,0 +1,4 @@ +muffins in tests - Rust +

Macro tests::muffins

source ·
macro_rules! muffins {
+    () => { ... };
+}
\ No newline at end of file diff --git a/tests/packet/fn.v4.html b/tests/packet/fn.v4.html new file mode 100644 index 00000000..4ab9d40f --- /dev/null +++ b/tests/packet/fn.v4.html @@ -0,0 +1,7 @@ +v4 in tests::packet - Rust +

Function tests::packet::v4

source ·
pub fn v4<'a>(
+    src: Ipv4Addr,
+    dst: Ipv4Addr,
+    payload: &[u8],
+    data: &'a mut [u8]
+) -> MutableIpv4Packet<'a>
\ No newline at end of file diff --git a/tests/packet/fn.v6.html b/tests/packet/fn.v6.html new file mode 100644 index 00000000..b4f22150 --- /dev/null +++ b/tests/packet/fn.v6.html @@ -0,0 +1,7 @@ +v6 in tests::packet - Rust +

Function tests::packet::v6

source ·
pub fn v6<'a>(
+    src: Ipv6Addr,
+    dst: Ipv6Addr,
+    payload: &[u8],
+    data: &'a mut [u8]
+) -> MutableIpv6Packet<'a>
\ No newline at end of file diff --git a/tests/packet/index.html b/tests/packet/index.html new file mode 100644 index 00000000..f51431fa --- /dev/null +++ b/tests/packet/index.html @@ -0,0 +1,2 @@ +tests::packet - Rust +

Module tests::packet

source ·

Functions§

\ No newline at end of file diff --git a/tests/packet/sidebar-items.js b/tests/packet/sidebar-items.js new file mode 100644 index 00000000..41ca0a91 --- /dev/null +++ b/tests/packet/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["v4","v6"]}; \ No newline at end of file diff --git a/tests/sidebar-items.js b/tests/sidebar-items.js new file mode 100644 index 00000000..e1a763c4 --- /dev/null +++ b/tests/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"macro":["expect_frames","muffins"],"mod":["data","packet","softnpu"]}; \ No newline at end of file diff --git a/tests/softnpu/fn.do_expect_frames.html b/tests/softnpu/fn.do_expect_frames.html new file mode 100644 index 00000000..7b407c26 --- /dev/null +++ b/tests/softnpu/fn.do_expect_frames.html @@ -0,0 +1,7 @@ +do_expect_frames in tests::softnpu - Rust +
pub fn do_expect_frames(
+    name: &str,
+    phy: &Arc<OuterPhy<RING, FBUF, MTU>>,
+    expected: &[RxFrame<'_>],
+    dmac: Option<[u8; 6]>
+)
\ No newline at end of file diff --git a/tests/softnpu/index.html b/tests/softnpu/index.html new file mode 100644 index 00000000..d0293a54 --- /dev/null +++ b/tests/softnpu/index.html @@ -0,0 +1,2 @@ +tests::softnpu - Rust +
\ No newline at end of file diff --git a/tests/softnpu/sidebar-items.js b/tests/softnpu/sidebar-items.js new file mode 100644 index 00000000..77feab0c --- /dev/null +++ b/tests/softnpu/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["do_expect_frames"],"struct":["InnerPhy","Interface4","Interface6","OuterPhy","OwnedFrame","RxFrame","SoftNpu","TxFrame"]}; \ No newline at end of file diff --git a/tests/softnpu/struct.InnerPhy.html b/tests/softnpu/struct.InnerPhy.html new file mode 100644 index 00000000..7444623c --- /dev/null +++ b/tests/softnpu/struct.InnerPhy.html @@ -0,0 +1,99 @@ +InnerPhy in tests::softnpu - Rust +

Struct tests::softnpu::InnerPhy

source ·
pub struct InnerPhy<const R: usize, const N: usize, const F: usize> {
+    pub index: usize,
+    /* private fields */
+}

Fields§

§index: usize

Implementations§

source§

impl<const R: usize, const N: usize, const F: usize> InnerPhy<R, N, F>

source

pub fn new( + index: usize, + rx_c: RingConsumer<R, N, F>, + tx_p: RingProducer<R, N, F> +) -> Self

Auto Trait Implementations§

§

impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for InnerPhy<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Send for InnerPhy<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> !Sync for InnerPhy<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Unpin for InnerPhy<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for InnerPhy<R, N, F>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.Interface4.html b/tests/softnpu/struct.Interface4.html new file mode 100644 index 00000000..7606264e --- /dev/null +++ b/tests/softnpu/struct.Interface4.html @@ -0,0 +1,101 @@ +Interface4 in tests::softnpu - Rust +

Struct tests::softnpu::Interface4

source ·
pub struct Interface4<const R: usize, const N: usize, const F: usize> {
+    pub phy: Arc<OuterPhy<R, N, F>>,
+    pub addr: Ipv4Addr,
+    pub sc_egress: u16,
+}

Fields§

§phy: Arc<OuterPhy<R, N, F>>§addr: Ipv4Addr§sc_egress: u16

Implementations§

source§

impl<const R: usize, const N: usize, const F: usize> Interface4<R, N, F>

source

pub fn new(phy: Arc<OuterPhy<R, N, F>>, addr: Ipv4Addr) -> Self

source

pub fn send( + &self, + mac: [u8; 6], + ip: Ipv4Addr, + payload: &[u8] +) -> Result<(), Error>

Auto Trait Implementations§

§

impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for Interface4<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Send for Interface4<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Sync for Interface4<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Unpin for Interface4<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for Interface4<R, N, F>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.Interface6.html b/tests/softnpu/struct.Interface6.html new file mode 100644 index 00000000..fabc9af7 --- /dev/null +++ b/tests/softnpu/struct.Interface6.html @@ -0,0 +1,101 @@ +Interface6 in tests::softnpu - Rust +

Struct tests::softnpu::Interface6

source ·
pub struct Interface6<const R: usize, const N: usize, const F: usize> {
+    pub phy: Arc<OuterPhy<R, N, F>>,
+    pub addr: Ipv6Addr,
+    pub sc_egress: u16,
+}

Fields§

§phy: Arc<OuterPhy<R, N, F>>§addr: Ipv6Addr§sc_egress: u16

Implementations§

source§

impl<const R: usize, const N: usize, const F: usize> Interface6<R, N, F>

source

pub fn new(phy: Arc<OuterPhy<R, N, F>>, addr: Ipv6Addr) -> Self

source

pub fn send( + &self, + mac: [u8; 6], + ip: Ipv6Addr, + payload: &[u8] +) -> Result<(), Error>

Auto Trait Implementations§

§

impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for Interface6<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Send for Interface6<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Sync for Interface6<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Unpin for Interface6<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for Interface6<R, N, F>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.OuterPhy.html b/tests/softnpu/struct.OuterPhy.html new file mode 100644 index 00000000..505f249f --- /dev/null +++ b/tests/softnpu/struct.OuterPhy.html @@ -0,0 +1,100 @@ +OuterPhy in tests::softnpu - Rust +

Struct tests::softnpu::OuterPhy

source ·
pub struct OuterPhy<const R: usize, const N: usize, const F: usize> {
+    pub index: usize,
+    pub mac: [u8; 6],
+    /* private fields */
+}

Fields§

§index: usize§mac: [u8; 6]

Implementations§

source§

impl<const R: usize, const N: usize, const F: usize> OuterPhy<R, N, F>

source

pub fn new( + index: usize, + rx_p: RingProducer<R, N, F>, + tx_c: RingConsumer<R, N, F> +) -> Self

source

pub fn send(&self, frames: &[TxFrame<'_>]) -> Result<(), Error>

source

pub fn recv(&self) -> Vec<OwnedFrame>

source

pub fn recv_buffer_len(&self) -> usize

source

pub fn tx_count(&self) -> usize

source

pub fn rx_count(&self) -> usize

Trait Implementations§

source§

impl<const R: usize, const N: usize, const F: usize> Send for OuterPhy<R, N, F>

source§

impl<const R: usize, const N: usize, const F: usize> Sync for OuterPhy<R, N, F>

Auto Trait Implementations§

§

impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for OuterPhy<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> Unpin for OuterPhy<R, N, F>

§

impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for OuterPhy<R, N, F>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.OwnedFrame.html b/tests/softnpu/struct.OwnedFrame.html new file mode 100644 index 00000000..ae23b0d4 --- /dev/null +++ b/tests/softnpu/struct.OwnedFrame.html @@ -0,0 +1,105 @@ +OwnedFrame in tests::softnpu - Rust +

Struct tests::softnpu::OwnedFrame

source ·
pub struct OwnedFrame {
+    pub dst: [u8; 6],
+    pub src: [u8; 6],
+    pub vid: Option<u16>,
+    pub ethertype: u16,
+    pub payload: Vec<u8>,
+}

Fields§

§dst: [u8; 6]§src: [u8; 6]§vid: Option<u16>§ethertype: u16§payload: Vec<u8>

Implementations§

source§

impl OwnedFrame

source

pub fn new( + dst: [u8; 6], + src: [u8; 6], + ethertype: u16, + vid: Option<u16>, + payload: Vec<u8> +) -> Self

Trait Implementations§

source§

impl Clone for OwnedFrame

source§

fn clone(&self) -> OwnedFrame

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.RxFrame.html b/tests/softnpu/struct.RxFrame.html new file mode 100644 index 00000000..9597458b --- /dev/null +++ b/tests/softnpu/struct.RxFrame.html @@ -0,0 +1,97 @@ +RxFrame in tests::softnpu - Rust +

Struct tests::softnpu::RxFrame

source ·
pub struct RxFrame<'a> {
+    pub src: [u8; 6],
+    pub ethertype: u16,
+    pub payload: &'a [u8],
+    pub vid: Option<u16>,
+}

Fields§

§src: [u8; 6]§ethertype: u16§payload: &'a [u8]§vid: Option<u16>

Implementations§

source§

impl<'a> RxFrame<'a>

source

pub fn new(src: [u8; 6], ethertype: u16, payload: &'a [u8]) -> Self

source

pub fn newv(src: [u8; 6], ethertype: u16, payload: &'a [u8], vid: u16) -> Self

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for RxFrame<'a>

§

impl<'a> Send for RxFrame<'a>

§

impl<'a> Sync for RxFrame<'a>

§

impl<'a> Unpin for RxFrame<'a>

§

impl<'a> UnwindSafe for RxFrame<'a>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.SoftNpu.html b/tests/softnpu/struct.SoftNpu.html new file mode 100644 index 00000000..98a2b683 --- /dev/null +++ b/tests/softnpu/struct.SoftNpu.html @@ -0,0 +1,101 @@ +SoftNpu in tests::softnpu - Rust +

Struct tests::softnpu::SoftNpu

source ·
pub struct SoftNpu<P: Pipeline> {
+    pub pipeline: Option<P>,
+    /* private fields */
+}

Fields§

§pipeline: Option<P>

Implementations§

source§

impl<P: Pipeline + 'static> SoftNpu<P>

source

pub fn new(radix: usize, pipeline: P, cpu_port: bool) -> Self

Create a new SoftNpu ASIC emulator. The radix indicates the number of +ports. The pipeline is the x4c compiled program that the ASIC will +run. When cpu_port is set to true, sidecar data in TxFrame elements +will be added to packets sent through port 0 (as a sidecar header) on +the way to the ASIC.

+
source

pub fn run(&mut self)

source

pub fn phy(&self, i: usize) -> Arc<OuterPhy<RING, FBUF, MTU>>

Auto Trait Implementations§

§

impl<P> !RefUnwindSafe for SoftNpu<P>

§

impl<P> Send for SoftNpu<P>

§

impl<P> !Sync for SoftNpu<P>

§

impl<P> Unpin for SoftNpu<P>
where + P: Unpin,

§

impl<P> !UnwindSafe for SoftNpu<P>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/tests/softnpu/struct.TxFrame.html b/tests/softnpu/struct.TxFrame.html new file mode 100644 index 00000000..c60a6001 --- /dev/null +++ b/tests/softnpu/struct.TxFrame.html @@ -0,0 +1,98 @@ +TxFrame in tests::softnpu - Rust +

Struct tests::softnpu::TxFrame

source ·
pub struct TxFrame<'a> {
+    pub dst: [u8; 6],
+    pub ethertype: u16,
+    pub payload: &'a [u8],
+    pub sc_egress: u16,
+    pub vid: Option<u16>,
+}

Fields§

§dst: [u8; 6]§ethertype: u16§payload: &'a [u8]§sc_egress: u16§vid: Option<u16>

Implementations§

source§

impl<'a> TxFrame<'a>

source

pub fn new(dst: [u8; 6], ethertype: u16, payload: &'a [u8]) -> Self

source

pub fn newv(dst: [u8; 6], ethertype: u16, payload: &'a [u8], vid: u16) -> Self

Auto Trait Implementations§

§

impl<'a> RefUnwindSafe for TxFrame<'a>

§

impl<'a> Send for TxFrame<'a>

§

impl<'a> Sync for TxFrame<'a>

§

impl<'a> Unpin for TxFrame<'a>

§

impl<'a> UnwindSafe for TxFrame<'a>

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/trait.impl/clap/derive/trait.Args.js b/trait.impl/clap/derive/trait.Args.js new file mode 100644 index 00000000..2108def3 --- /dev/null +++ b/trait.impl/clap/derive/trait.Args.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"x4c":[["impl Args for Opts"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/clap/derive/trait.CommandFactory.js b/trait.impl/clap/derive/trait.CommandFactory.js new file mode 100644 index 00000000..c8b350e8 --- /dev/null +++ b/trait.impl/clap/derive/trait.CommandFactory.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"x4c":[["impl CommandFactory for Opts"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/clap/derive/trait.FromArgMatches.js b/trait.impl/clap/derive/trait.FromArgMatches.js new file mode 100644 index 00000000..5054f038 --- /dev/null +++ b/trait.impl/clap/derive/trait.FromArgMatches.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"x4c":[["impl FromArgMatches for Opts"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/clap/derive/trait.Parser.js b/trait.impl/clap/derive/trait.Parser.js new file mode 100644 index 00000000..58e2a077 --- /dev/null +++ b/trait.impl/clap/derive/trait.Parser.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"x4c":[["impl Parser for Opts"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/clap/derive/trait.ValueEnum.js b/trait.impl/clap/derive/trait.ValueEnum.js new file mode 100644 index 00000000..b563b5e8 --- /dev/null +++ b/trait.impl/clap/derive/trait.ValueEnum.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"x4c":[["impl ValueEnum for Target"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/clone/trait.Clone.js b/trait.impl/core/clone/trait.Clone.js new file mode 100644 index 00000000..dbf83203 --- /dev/null +++ b/trait.impl/core/clone/trait.Clone.js @@ -0,0 +1,10 @@ +(function() {var implementors = { +"hello_world":[["impl Clone for ethernet_h"],["impl Clone for ingress_metadata_t"],["impl Clone for egress_metadata_t"],["impl Clone for headers_t"]], +"p4":[["impl Clone for Lvalue"],["impl Clone for Statement"],["impl Clone for Constant"],["impl Clone for Level"],["impl Clone for Control"],["impl Clone for Kind"],["impl Clone for NameInfo"],["impl Clone for Expression"],["impl Clone for DeclarationInfo"],["impl Clone for ExpressionKind"],["impl Clone for BinOp"],["impl Clone for Parser"],["impl Clone for SelectElement"],["impl Clone for ActionRef"],["impl Clone for Diagnostic"],["impl Clone for Direction"],["impl Clone for KeySetElement"],["impl Clone for ConstTableEntry"],["impl Clone for Type"],["impl Clone for ActionParameter"],["impl Clone for IfBlock"],["impl Clone for Extern"],["impl Clone for KeySetElementValue"],["impl Clone for ExternMethod"],["impl Clone for StatementBlock"],["impl Clone for Header"],["impl Clone for ElseIfBlock"],["impl Clone for Variable"],["impl Clone for ControlParameter"],["impl Clone for Table"],["impl Clone for Select"],["impl Clone for Struct"],["impl Clone for Transition"],["impl Clone for Typedef"],["impl Clone for Call"],["impl Clone for StructMember"],["impl Clone for Action"],["impl Clone for State"],["impl Clone for Token"],["impl Clone for MatchKind"],["impl Clone for HeaderMember"]], +"p4_macro_test":[["impl Clone for ethernet_t"],["impl Clone for headers_t"]], +"p4rs":[["impl Clone for Key"],["impl Clone for Ternary"],["impl<const D: usize, A: Clone + Clone> Clone for TableEntry<D, A>"],["impl Clone for BigUintKey"],["impl Clone for Prefix"]], +"sidecar_lite":[["impl Clone for sidecar_h"],["impl Clone for icmp_h"],["impl Clone for geneve_h"],["impl Clone for ethernet_h"],["impl Clone for udp_h"],["impl Clone for headers_t"],["impl Clone for vlan_h"],["impl Clone for ddm_h"],["impl Clone for egress_metadata_t"],["impl Clone for ingress_metadata_t"],["impl Clone for arp_h"],["impl Clone for ddm_element_t"],["impl Clone for ipv4_h"],["impl Clone for ipv6_h"],["impl Clone for tcp_h"]], +"tests":[["impl Clone for OwnedFrame"]], +"vlan_switch":[["impl Clone for headers_t"],["impl Clone for ipv6_h"],["impl Clone for udp_h"],["impl Clone for ethernet_h"],["impl Clone for vlan_h"],["impl Clone for ddm_h"],["impl Clone for ipv4_h"],["impl Clone for ingress_metadata_t"],["impl Clone for icmp_h"],["impl Clone for ddm_element_t"],["impl Clone for arp_h"],["impl Clone for geneve_h"],["impl Clone for sidecar_h"],["impl Clone for egress_metadata_t"],["impl Clone for tcp_h"]], +"x4c":[["impl Clone for Target"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Eq.js b/trait.impl/core/cmp/trait.Eq.js new file mode 100644 index 00000000..1756eff6 --- /dev/null +++ b/trait.impl/core/cmp/trait.Eq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl Eq for Direction"],["impl Eq for Token"],["impl Eq for Kind"],["impl Eq for BinOp"],["impl Eq for DeclarationInfo"],["impl Eq for Expression"],["impl Eq for Lvalue"],["impl Eq for Level"],["impl Eq for Type"]], +"p4rs":[["impl<'a> Eq for Bit<'a, 8>"],["impl Eq for Ternary"],["impl Eq for Prefix"],["impl<const D: usize, A: Clone> Eq for TableEntry<D, A>"],["impl Eq for BigUintKey"],["impl Eq for Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.Ord.js b/trait.impl/core/cmp/trait.Ord.js new file mode 100644 index 00000000..fc5b548c --- /dev/null +++ b/trait.impl/core/cmp/trait.Ord.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4":[["impl Ord for Lvalue"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialEq.js b/trait.impl/core/cmp/trait.PartialEq.js new file mode 100644 index 00000000..d418ac78 --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl PartialEq for Direction"],["impl PartialEq for Level"],["impl PartialEq for BinOp"],["impl PartialEq for Lvalue"],["impl PartialEq for Token"],["impl PartialEq for Type"],["impl PartialEq for Kind"],["impl PartialEq for Control"],["impl PartialEq for DeclarationInfo"],["impl PartialEq for Expression"]], +"p4rs":[["impl PartialEq for Prefix"],["impl PartialEq for Key"],["impl<'a> PartialEq for Bit<'a, 8>"],["impl PartialEq for BigUintKey"],["impl PartialEq for Ternary"],["impl<const D: usize, A: Clone> PartialEq for TableEntry<D, A>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/cmp/trait.PartialOrd.js b/trait.impl/core/cmp/trait.PartialOrd.js new file mode 100644 index 00000000..c0436256 --- /dev/null +++ b/trait.impl/core/cmp/trait.PartialOrd.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4":[["impl PartialOrd for Lvalue"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/convert/trait.From.js b/trait.impl/core/convert/trait.From.js new file mode 100644 index 00000000..bdd44287 --- /dev/null +++ b/trait.impl/core/convert/trait.From.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl From<TokenError> for Error"],["impl From<ParserError> for Error"],["impl From<Vec<SemanticError>> for Error"]], +"p4rs":[["impl<'a> From<Bit<'a, 16>> for u16"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/default/trait.Default.js b/trait.impl/core/default/trait.Default.js new file mode 100644 index 00000000..ac84cb84 --- /dev/null +++ b/trait.impl/core/default/trait.Default.js @@ -0,0 +1,8 @@ +(function() {var implementors = { +"hello_world":[["impl Default for egress_metadata_t"],["impl Default for ingress_metadata_t"],["impl Default for ethernet_h"],["impl Default for headers_t"]], +"p4":[["impl Default for PreprocessorResult"],["impl Default for Diagnostics"],["impl Default for StatementBlock"],["impl Default for Select"],["impl Default for Hlir"],["impl Default for AST"],["impl Default for PreprocessorElements"]], +"p4_macro_test":[["impl Default for ethernet_t"],["impl Default for headers_t"]], +"p4rs":[["impl Default for Csum"],["impl Default for Checksum"],["impl Default for Ternary"],["impl<const D: usize, A: Clone> Default for Table<D, A>"],["impl Default for Key"]], +"sidecar_lite":[["impl Default for udp_h"],["impl Default for headers_t"],["impl Default for arp_h"],["impl Default for ethernet_h"],["impl Default for egress_metadata_t"],["impl Default for icmp_h"],["impl Default for vlan_h"],["impl Default for ddm_h"],["impl Default for geneve_h"],["impl Default for tcp_h"],["impl Default for ingress_metadata_t"],["impl Default for sidecar_h"],["impl Default for ipv4_h"],["impl Default for ddm_element_t"],["impl Default for ipv6_h"]], +"vlan_switch":[["impl Default for tcp_h"],["impl Default for geneve_h"],["impl Default for ddm_h"],["impl Default for ingress_metadata_t"],["impl Default for arp_h"],["impl Default for ipv6_h"],["impl Default for icmp_h"],["impl Default for vlan_h"],["impl Default for ddm_element_t"],["impl Default for sidecar_h"],["impl Default for egress_metadata_t"],["impl Default for udp_h"],["impl Default for ipv4_h"],["impl Default for headers_t"],["impl Default for ethernet_h"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/error/trait.Error.js b/trait.impl/core/error/trait.Error.js new file mode 100644 index 00000000..8c21343a --- /dev/null +++ b/trait.impl/core/error/trait.Error.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl Error for PreprocessorError"],["impl Error for Error"],["impl Error for SemanticError"],["impl Error for TokenError"],["impl Error for ParserError"]], +"p4rs":[["impl Error for TryFromSliceError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Debug.js b/trait.impl/core/fmt/trait.Debug.js new file mode 100644 index 00000000..9f3014bc --- /dev/null +++ b/trait.impl/core/fmt/trait.Debug.js @@ -0,0 +1,8 @@ +(function() {var implementors = { +"hello_world":[["impl Debug for ethernet_h"],["impl Debug for egress_metadata_t"],["impl Debug for headers_t"],["impl Debug for ingress_metadata_t"]], +"p4":[["impl Debug for ActionRef"],["impl Debug for SemanticError"],["impl Debug for PackageInstance"],["impl Debug for Call"],["impl Debug for ConstTableEntry"],["impl Debug for Struct"],["impl Debug for Lvalue"],["impl Debug for Control"],["impl Debug for PackageParameter"],["impl Debug for NameInfo"],["impl Debug for BinOp"],["impl Debug for AST"],["impl Debug for PreprocessorError"],["impl Debug for Package"],["impl Debug for SelectElement"],["impl Debug for Constant"],["impl Debug for ParserError"],["impl Debug for Statement"],["impl Debug for StatementBlock"],["impl Debug for TokenError"],["impl Debug for State"],["impl Debug for Token"],["impl Debug for DeclarationInfo"],["impl Debug for Kind"],["impl Debug for MatchKind"],["impl Debug for Direction"],["impl Debug for ElseIfBlock"],["impl Debug for Typedef"],["impl Debug for Error"],["impl Debug for IfBlock"],["impl Debug for Transition"],["impl Debug for KeySetElement"],["impl Debug for KeySetElementValue"],["impl Debug for Extern"],["impl Debug for ControlParameter"],["impl Debug for PreprocessorResult"],["impl Debug for Table"],["impl Debug for Header"],["impl Debug for Diagnostic"],["impl Debug for HeaderMember"],["impl Debug for Level"],["impl Debug for Variable"],["impl Debug for PreprocessorElements"],["impl Debug for Expression"],["impl Debug for ExpressionKind"],["impl Debug for Select"],["impl Debug for ActionParameter"],["impl Debug for Action"],["impl Debug for Type"],["impl Debug for Diagnostics"],["impl Debug for Hlir"],["impl Debug for ExternMethod"],["impl Debug for Parser"],["impl Debug for StructMember"]], +"p4_macro_test":[["impl Debug for ethernet_t"],["impl Debug for headers_t"]], +"p4rs":[["impl Debug for Key"],["impl Debug for Prefix"],["impl Debug for BigUintKey"],["impl Debug for TableEntry"],["impl<'a, const N: usize> Debug for Bit<'a, N>"],["impl Debug for Ternary"],["impl<'a> Debug for packet_out<'a>"],["impl<'a> Debug for packet_in<'a>"],["impl<const D: usize, A: Clone> Debug for TableEntry<D, A>"],["impl Debug for TryFromSliceError"]], +"sidecar_lite":[["impl Debug for ingress_metadata_t"],["impl Debug for ethernet_h"],["impl Debug for ddm_element_t"],["impl Debug for tcp_h"],["impl Debug for ipv6_h"],["impl Debug for ipv4_h"],["impl Debug for egress_metadata_t"],["impl Debug for geneve_h"],["impl Debug for icmp_h"],["impl Debug for vlan_h"],["impl Debug for ddm_h"],["impl Debug for udp_h"],["impl Debug for headers_t"],["impl Debug for arp_h"],["impl Debug for sidecar_h"]], +"vlan_switch":[["impl Debug for ipv4_h"],["impl Debug for icmp_h"],["impl Debug for ddm_h"],["impl Debug for egress_metadata_t"],["impl Debug for vlan_h"],["impl Debug for ethernet_h"],["impl Debug for ddm_element_t"],["impl Debug for tcp_h"],["impl Debug for udp_h"],["impl Debug for headers_t"],["impl Debug for arp_h"],["impl Debug for sidecar_h"],["impl Debug for ipv6_h"],["impl Debug for ingress_metadata_t"],["impl Debug for geneve_h"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.Display.js b/trait.impl/core/fmt/trait.Display.js new file mode 100644 index 00000000..821cff64 --- /dev/null +++ b/trait.impl/core/fmt/trait.Display.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl Display for Error"],["impl Display for TokenError"],["impl Display for SemanticError"],["impl Display for Token"],["impl Display for Kind"],["impl Display for Type"],["impl Display for ParserError"],["impl Display for PreprocessorError"]], +"p4rs":[["impl Display for TryFromSliceError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/fmt/trait.LowerHex.js b/trait.impl/core/fmt/trait.LowerHex.js new file mode 100644 index 00000000..d02b17db --- /dev/null +++ b/trait.impl/core/fmt/trait.LowerHex.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4rs":[["impl<'a, const N: usize> LowerHex for Bit<'a, N>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/hash/trait.Hash.js b/trait.impl/core/hash/trait.Hash.js new file mode 100644 index 00000000..0d5a569b --- /dev/null +++ b/trait.impl/core/hash/trait.Hash.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl Hash for Kind"],["impl Hash for Expression"],["impl Hash for Lvalue"],["impl Hash for Token"]], +"p4rs":[["impl Hash for Prefix"],["impl<const D: usize, A: Clone> Hash for TableEntry<D, A>"],["impl<'a> Hash for Bit<'a, 8>"],["impl Hash for BigUintKey"],["impl Hash for Ternary"],["impl Hash for Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Copy.js b/trait.impl/core/marker/trait.Copy.js new file mode 100644 index 00000000..db621ec1 --- /dev/null +++ b/trait.impl/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4":[["impl Copy for Direction"],["impl Copy for BinOp"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Freeze.js b/trait.impl/core/marker/trait.Freeze.js new file mode 100644 index 00000000..4c919cb1 --- /dev/null +++ b/trait.impl/core/marker/trait.Freeze.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"hello_world":[["impl Freeze for headers_t",1,["hello_world::headers_t"]],["impl Freeze for ethernet_h",1,["hello_world::ethernet_h"]],["impl Freeze for egress_metadata_t",1,["hello_world::egress_metadata_t"]],["impl Freeze for ingress_metadata_t",1,["hello_world::ingress_metadata_t"]],["impl Freeze for main_pipeline",1,["hello_world::main_pipeline"]]], +"p4":[["impl Freeze for AST",1,["p4::ast::AST"]],["impl<'a> Freeze for UserDefinedType<'a>",1,["p4::ast::UserDefinedType"]],["impl Freeze for PackageInstance",1,["p4::ast::PackageInstance"]],["impl Freeze for Package",1,["p4::ast::Package"]],["impl Freeze for PackageParameter",1,["p4::ast::PackageParameter"]],["impl Freeze for Type",1,["p4::ast::Type"]],["impl Freeze for Typedef",1,["p4::ast::Typedef"]],["impl Freeze for Constant",1,["p4::ast::Constant"]],["impl Freeze for Variable",1,["p4::ast::Variable"]],["impl Freeze for Expression",1,["p4::ast::Expression"]],["impl Freeze for ExpressionKind",1,["p4::ast::ExpressionKind"]],["impl Freeze for BinOp",1,["p4::ast::BinOp"]],["impl Freeze for Header",1,["p4::ast::Header"]],["impl Freeze for HeaderMember",1,["p4::ast::HeaderMember"]],["impl Freeze for Struct",1,["p4::ast::Struct"]],["impl Freeze for StructMember",1,["p4::ast::StructMember"]],["impl Freeze for Control",1,["p4::ast::Control"]],["impl Freeze for Parser",1,["p4::ast::Parser"]],["impl Freeze for ControlParameter",1,["p4::ast::ControlParameter"]],["impl Freeze for Direction",1,["p4::ast::Direction"]],["impl Freeze for StatementBlock",1,["p4::ast::StatementBlock"]],["impl Freeze for Action",1,["p4::ast::Action"]],["impl Freeze for ActionParameter",1,["p4::ast::ActionParameter"]],["impl Freeze for Table",1,["p4::ast::Table"]],["impl Freeze for ConstTableEntry",1,["p4::ast::ConstTableEntry"]],["impl Freeze for KeySetElement",1,["p4::ast::KeySetElement"]],["impl Freeze for KeySetElementValue",1,["p4::ast::KeySetElementValue"]],["impl Freeze for ActionRef",1,["p4::ast::ActionRef"]],["impl Freeze for MatchKind",1,["p4::ast::MatchKind"]],["impl Freeze for Statement",1,["p4::ast::Statement"]],["impl Freeze for IfBlock",1,["p4::ast::IfBlock"]],["impl Freeze for ElseIfBlock",1,["p4::ast::ElseIfBlock"]],["impl Freeze for Call",1,["p4::ast::Call"]],["impl Freeze for Lvalue",1,["p4::ast::Lvalue"]],["impl Freeze for State",1,["p4::ast::State"]],["impl Freeze for Transition",1,["p4::ast::Transition"]],["impl Freeze for Select",1,["p4::ast::Select"]],["impl Freeze for SelectElement",1,["p4::ast::SelectElement"]],["impl Freeze for Extern",1,["p4::ast::Extern"]],["impl Freeze for ExternMethod",1,["p4::ast::ExternMethod"]],["impl Freeze for DeclarationInfo",1,["p4::ast::DeclarationInfo"]],["impl Freeze for NameInfo",1,["p4::ast::NameInfo"]],["impl Freeze for Diagnostic",1,["p4::check::Diagnostic"]],["impl Freeze for Level",1,["p4::check::Level"]],["impl Freeze for Diagnostics",1,["p4::check::Diagnostics"]],["impl Freeze for ControlChecker",1,["p4::check::ControlChecker"]],["impl<'a> Freeze for ApplyCallChecker<'a>",1,["p4::check::ApplyCallChecker"]],["impl Freeze for ParserChecker",1,["p4::check::ParserChecker"]],["impl Freeze for StructChecker",1,["p4::check::StructChecker"]],["impl Freeze for HeaderChecker",1,["p4::check::HeaderChecker"]],["impl Freeze for ExpressionTypeChecker",1,["p4::check::ExpressionTypeChecker"]],["impl Freeze for SemanticError",1,["p4::error::SemanticError"]],["impl Freeze for ParserError",1,["p4::error::ParserError"]],["impl Freeze for TokenError",1,["p4::error::TokenError"]],["impl Freeze for Error",1,["p4::error::Error"]],["impl Freeze for PreprocessorError",1,["p4::error::PreprocessorError"]],["impl Freeze for Hlir",1,["p4::hlir::Hlir"]],["impl<'a> Freeze for HlirGenerator<'a>",1,["p4::hlir::HlirGenerator"]],["impl Freeze for Kind",1,["p4::lexer::Kind"]],["impl Freeze for Token",1,["p4::lexer::Token"]],["impl<'a> Freeze for Lexer<'a>",1,["p4::lexer::Lexer"]],["impl<'a> Freeze for Parser<'a>",1,["p4::parser::Parser"]],["impl<'a, 'b> Freeze for GlobalParser<'a, 'b>",1,["p4::parser::GlobalParser"]],["impl<'a, 'b> Freeze for ControlParser<'a, 'b>",1,["p4::parser::ControlParser"]],["impl<'a, 'b> Freeze for ActionParser<'a, 'b>",1,["p4::parser::ActionParser"]],["impl<'a, 'b> Freeze for TableParser<'a, 'b>",1,["p4::parser::TableParser"]],["impl<'a, 'b> Freeze for StatementParser<'a, 'b>",1,["p4::parser::StatementParser"]],["impl<'a, 'b> Freeze for IfElseParser<'a, 'b>",1,["p4::parser::IfElseParser"]],["impl<'a, 'b> Freeze for ExpressionParser<'a, 'b>",1,["p4::parser::ExpressionParser"]],["impl<'a, 'b> Freeze for ParserParser<'a, 'b>",1,["p4::parser::ParserParser"]],["impl<'a, 'b> Freeze for StateParser<'a, 'b>",1,["p4::parser::StateParser"]],["impl<'a, 'b> Freeze for SelectParser<'a, 'b>",1,["p4::parser::SelectParser"]],["impl Freeze for PreprocessorResult",1,["p4::preprocessor::PreprocessorResult"]],["impl Freeze for PreprocessorElements",1,["p4::preprocessor::PreprocessorElements"]]], +"p4_macro_test":[["impl Freeze for ethernet_t",1,["p4_macro_test::ethernet_t"]],["impl Freeze for headers_t",1,["p4_macro_test::headers_t"]]], +"p4_rust":[["impl Freeze for Settings",1,["p4_rust::Settings"]],["impl Freeze for Sanitizer",1,["p4_rust::Sanitizer"]]], +"p4rs":[["impl Freeze for TryFromSliceError",1,["p4rs::error::TryFromSliceError"]],["impl Freeze for Csum",1,["p4rs::checksum::Csum"]],["impl Freeze for Checksum",1,["p4rs::externs::Checksum"]],["impl Freeze for BigUintKey",1,["p4rs::table::BigUintKey"]],["impl Freeze for Key",1,["p4rs::table::Key"]],["impl Freeze for Ternary",1,["p4rs::table::Ternary"]],["impl Freeze for Prefix",1,["p4rs::table::Prefix"]],["impl<const D: usize, A> Freeze for Table<D, A>",1,["p4rs::table::Table"]],["impl<const D: usize, A> Freeze for TableEntry<D, A>
where\n A: Freeze,
",1,["p4rs::table::TableEntry"]],["impl<'a, const N: usize> Freeze for Bit<'a, N>",1,["p4rs::Bit"]],["impl<'a> Freeze for packet_in<'a>",1,["p4rs::packet_in"]],["impl<'a> Freeze for packet_out<'a>",1,["p4rs::packet_out"]],["impl Freeze for TableEntry",1,["p4rs::TableEntry"]],["impl Freeze for AlignedU128",1,["p4rs::AlignedU128"]]], +"sidecar_lite":[["impl Freeze for tcp_h",1,["sidecar_lite::tcp_h"]],["impl Freeze for ddm_h",1,["sidecar_lite::ddm_h"]],["impl Freeze for sidecar_h",1,["sidecar_lite::sidecar_h"]],["impl Freeze for vlan_h",1,["sidecar_lite::vlan_h"]],["impl Freeze for ddm_element_t",1,["sidecar_lite::ddm_element_t"]],["impl Freeze for ingress_metadata_t",1,["sidecar_lite::ingress_metadata_t"]],["impl Freeze for ipv6_h",1,["sidecar_lite::ipv6_h"]],["impl Freeze for ipv4_h",1,["sidecar_lite::ipv4_h"]],["impl Freeze for icmp_h",1,["sidecar_lite::icmp_h"]],["impl Freeze for ethernet_h",1,["sidecar_lite::ethernet_h"]],["impl Freeze for arp_h",1,["sidecar_lite::arp_h"]],["impl Freeze for headers_t",1,["sidecar_lite::headers_t"]],["impl Freeze for egress_metadata_t",1,["sidecar_lite::egress_metadata_t"]],["impl Freeze for geneve_h",1,["sidecar_lite::geneve_h"]],["impl Freeze for udp_h",1,["sidecar_lite::udp_h"]],["impl Freeze for main_pipeline",1,["sidecar_lite::main_pipeline"]]], +"tests":[["impl<P> Freeze for SoftNpu<P>
where\n P: Freeze,
",1,["tests::softnpu::SoftNpu"]],["impl<const R: usize, const N: usize, const F: usize> !Freeze for InnerPhy<R, N, F>",1,["tests::softnpu::InnerPhy"]],["impl<const R: usize, const N: usize, const F: usize> !Freeze for OuterPhy<R, N, F>",1,["tests::softnpu::OuterPhy"]],["impl<const R: usize, const N: usize, const F: usize> Freeze for Interface6<R, N, F>",1,["tests::softnpu::Interface6"]],["impl<const R: usize, const N: usize, const F: usize> Freeze for Interface4<R, N, F>",1,["tests::softnpu::Interface4"]],["impl<'a> Freeze for TxFrame<'a>",1,["tests::softnpu::TxFrame"]],["impl<'a> Freeze for RxFrame<'a>",1,["tests::softnpu::RxFrame"]],["impl Freeze for OwnedFrame",1,["tests::softnpu::OwnedFrame"]]], +"vlan_switch":[["impl Freeze for ddm_h",1,["vlan_switch::ddm_h"]],["impl Freeze for egress_metadata_t",1,["vlan_switch::egress_metadata_t"]],["impl Freeze for udp_h",1,["vlan_switch::udp_h"]],["impl Freeze for ddm_element_t",1,["vlan_switch::ddm_element_t"]],["impl Freeze for ingress_metadata_t",1,["vlan_switch::ingress_metadata_t"]],["impl Freeze for tcp_h",1,["vlan_switch::tcp_h"]],["impl Freeze for vlan_h",1,["vlan_switch::vlan_h"]],["impl Freeze for ipv4_h",1,["vlan_switch::ipv4_h"]],["impl Freeze for ipv6_h",1,["vlan_switch::ipv6_h"]],["impl Freeze for icmp_h",1,["vlan_switch::icmp_h"]],["impl Freeze for geneve_h",1,["vlan_switch::geneve_h"]],["impl Freeze for arp_h",1,["vlan_switch::arp_h"]],["impl Freeze for headers_t",1,["vlan_switch::headers_t"]],["impl Freeze for ethernet_h",1,["vlan_switch::ethernet_h"]],["impl Freeze for sidecar_h",1,["vlan_switch::sidecar_h"]],["impl Freeze for main_pipeline",1,["vlan_switch::main_pipeline"]]], +"x4c":[["impl Freeze for Opts",1,["x4c::Opts"]],["impl Freeze for Target",1,["x4c::Target"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Send.js b/trait.impl/core/marker/trait.Send.js new file mode 100644 index 00000000..7f0bdba5 --- /dev/null +++ b/trait.impl/core/marker/trait.Send.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"hello_world":[["impl Send for headers_t",1,["hello_world::headers_t"]],["impl Send for ethernet_h",1,["hello_world::ethernet_h"]],["impl Send for egress_metadata_t",1,["hello_world::egress_metadata_t"]],["impl Send for ingress_metadata_t",1,["hello_world::ingress_metadata_t"]],["impl Send for main_pipeline"]], +"p4":[["impl Send for AST",1,["p4::ast::AST"]],["impl<'a> Send for UserDefinedType<'a>",1,["p4::ast::UserDefinedType"]],["impl Send for PackageInstance",1,["p4::ast::PackageInstance"]],["impl Send for Package",1,["p4::ast::Package"]],["impl Send for PackageParameter",1,["p4::ast::PackageParameter"]],["impl Send for Type",1,["p4::ast::Type"]],["impl Send for Typedef",1,["p4::ast::Typedef"]],["impl Send for Constant",1,["p4::ast::Constant"]],["impl Send for Variable",1,["p4::ast::Variable"]],["impl Send for Expression",1,["p4::ast::Expression"]],["impl Send for ExpressionKind",1,["p4::ast::ExpressionKind"]],["impl Send for BinOp",1,["p4::ast::BinOp"]],["impl Send for Header",1,["p4::ast::Header"]],["impl Send for HeaderMember",1,["p4::ast::HeaderMember"]],["impl Send for Struct",1,["p4::ast::Struct"]],["impl Send for StructMember",1,["p4::ast::StructMember"]],["impl Send for Control",1,["p4::ast::Control"]],["impl Send for Parser",1,["p4::ast::Parser"]],["impl Send for ControlParameter",1,["p4::ast::ControlParameter"]],["impl Send for Direction",1,["p4::ast::Direction"]],["impl Send for StatementBlock",1,["p4::ast::StatementBlock"]],["impl Send for Action",1,["p4::ast::Action"]],["impl Send for ActionParameter",1,["p4::ast::ActionParameter"]],["impl Send for Table",1,["p4::ast::Table"]],["impl Send for ConstTableEntry",1,["p4::ast::ConstTableEntry"]],["impl Send for KeySetElement",1,["p4::ast::KeySetElement"]],["impl Send for KeySetElementValue",1,["p4::ast::KeySetElementValue"]],["impl Send for ActionRef",1,["p4::ast::ActionRef"]],["impl Send for MatchKind",1,["p4::ast::MatchKind"]],["impl Send for Statement",1,["p4::ast::Statement"]],["impl Send for IfBlock",1,["p4::ast::IfBlock"]],["impl Send for ElseIfBlock",1,["p4::ast::ElseIfBlock"]],["impl Send for Call",1,["p4::ast::Call"]],["impl Send for Lvalue",1,["p4::ast::Lvalue"]],["impl Send for State",1,["p4::ast::State"]],["impl Send for Transition",1,["p4::ast::Transition"]],["impl Send for Select",1,["p4::ast::Select"]],["impl Send for SelectElement",1,["p4::ast::SelectElement"]],["impl Send for Extern",1,["p4::ast::Extern"]],["impl Send for ExternMethod",1,["p4::ast::ExternMethod"]],["impl Send for DeclarationInfo",1,["p4::ast::DeclarationInfo"]],["impl Send for NameInfo",1,["p4::ast::NameInfo"]],["impl Send for Diagnostic",1,["p4::check::Diagnostic"]],["impl Send for Level",1,["p4::check::Level"]],["impl Send for Diagnostics",1,["p4::check::Diagnostics"]],["impl Send for ControlChecker",1,["p4::check::ControlChecker"]],["impl<'a> Send for ApplyCallChecker<'a>",1,["p4::check::ApplyCallChecker"]],["impl Send for ParserChecker",1,["p4::check::ParserChecker"]],["impl Send for StructChecker",1,["p4::check::StructChecker"]],["impl Send for HeaderChecker",1,["p4::check::HeaderChecker"]],["impl Send for ExpressionTypeChecker",1,["p4::check::ExpressionTypeChecker"]],["impl Send for SemanticError",1,["p4::error::SemanticError"]],["impl Send for ParserError",1,["p4::error::ParserError"]],["impl Send for TokenError",1,["p4::error::TokenError"]],["impl Send for Error",1,["p4::error::Error"]],["impl Send for PreprocessorError",1,["p4::error::PreprocessorError"]],["impl Send for Hlir",1,["p4::hlir::Hlir"]],["impl<'a> Send for HlirGenerator<'a>",1,["p4::hlir::HlirGenerator"]],["impl Send for Kind",1,["p4::lexer::Kind"]],["impl Send for Token",1,["p4::lexer::Token"]],["impl<'a> Send for Lexer<'a>",1,["p4::lexer::Lexer"]],["impl<'a> Send for Parser<'a>",1,["p4::parser::Parser"]],["impl<'a, 'b> Send for GlobalParser<'a, 'b>",1,["p4::parser::GlobalParser"]],["impl<'a, 'b> Send for ControlParser<'a, 'b>",1,["p4::parser::ControlParser"]],["impl<'a, 'b> Send for ActionParser<'a, 'b>",1,["p4::parser::ActionParser"]],["impl<'a, 'b> Send for TableParser<'a, 'b>",1,["p4::parser::TableParser"]],["impl<'a, 'b> Send for StatementParser<'a, 'b>",1,["p4::parser::StatementParser"]],["impl<'a, 'b> Send for IfElseParser<'a, 'b>",1,["p4::parser::IfElseParser"]],["impl<'a, 'b> Send for ExpressionParser<'a, 'b>",1,["p4::parser::ExpressionParser"]],["impl<'a, 'b> Send for ParserParser<'a, 'b>",1,["p4::parser::ParserParser"]],["impl<'a, 'b> Send for StateParser<'a, 'b>",1,["p4::parser::StateParser"]],["impl<'a, 'b> Send for SelectParser<'a, 'b>",1,["p4::parser::SelectParser"]],["impl Send for PreprocessorResult",1,["p4::preprocessor::PreprocessorResult"]],["impl Send for PreprocessorElements",1,["p4::preprocessor::PreprocessorElements"]]], +"p4_macro_test":[["impl Send for ethernet_t",1,["p4_macro_test::ethernet_t"]],["impl Send for headers_t",1,["p4_macro_test::headers_t"]]], +"p4_rust":[["impl Send for Settings",1,["p4_rust::Settings"]],["impl Send for Sanitizer",1,["p4_rust::Sanitizer"]]], +"p4rs":[["impl Send for TryFromSliceError",1,["p4rs::error::TryFromSliceError"]],["impl Send for Csum",1,["p4rs::checksum::Csum"]],["impl Send for Checksum",1,["p4rs::externs::Checksum"]],["impl Send for BigUintKey",1,["p4rs::table::BigUintKey"]],["impl Send for Key",1,["p4rs::table::Key"]],["impl Send for Ternary",1,["p4rs::table::Ternary"]],["impl Send for Prefix",1,["p4rs::table::Prefix"]],["impl<const D: usize, A> Send for Table<D, A>
where\n A: Send,
",1,["p4rs::table::Table"]],["impl<const D: usize, A> Send for TableEntry<D, A>
where\n A: Send,
",1,["p4rs::table::TableEntry"]],["impl<'a, const N: usize> Send for Bit<'a, N>",1,["p4rs::Bit"]],["impl<'a> Send for packet_in<'a>",1,["p4rs::packet_in"]],["impl<'a> Send for packet_out<'a>",1,["p4rs::packet_out"]],["impl Send for TableEntry",1,["p4rs::TableEntry"]],["impl Send for AlignedU128",1,["p4rs::AlignedU128"]]], +"sidecar_lite":[["impl Send for tcp_h",1,["sidecar_lite::tcp_h"]],["impl Send for ddm_h",1,["sidecar_lite::ddm_h"]],["impl Send for sidecar_h",1,["sidecar_lite::sidecar_h"]],["impl Send for vlan_h",1,["sidecar_lite::vlan_h"]],["impl Send for ddm_element_t",1,["sidecar_lite::ddm_element_t"]],["impl Send for ingress_metadata_t",1,["sidecar_lite::ingress_metadata_t"]],["impl Send for ipv6_h",1,["sidecar_lite::ipv6_h"]],["impl Send for ipv4_h",1,["sidecar_lite::ipv4_h"]],["impl Send for icmp_h",1,["sidecar_lite::icmp_h"]],["impl Send for ethernet_h",1,["sidecar_lite::ethernet_h"]],["impl Send for arp_h",1,["sidecar_lite::arp_h"]],["impl Send for headers_t",1,["sidecar_lite::headers_t"]],["impl Send for egress_metadata_t",1,["sidecar_lite::egress_metadata_t"]],["impl Send for geneve_h",1,["sidecar_lite::geneve_h"]],["impl Send for udp_h",1,["sidecar_lite::udp_h"]],["impl Send for main_pipeline"]], +"tests":[["impl<P> Send for SoftNpu<P>",1,["tests::softnpu::SoftNpu"]],["impl<const R: usize, const N: usize, const F: usize> Send for InnerPhy<R, N, F>",1,["tests::softnpu::InnerPhy"]],["impl<const R: usize, const N: usize, const F: usize> Send for Interface6<R, N, F>",1,["tests::softnpu::Interface6"]],["impl<const R: usize, const N: usize, const F: usize> Send for Interface4<R, N, F>",1,["tests::softnpu::Interface4"]],["impl<'a> Send for TxFrame<'a>",1,["tests::softnpu::TxFrame"]],["impl<'a> Send for RxFrame<'a>",1,["tests::softnpu::RxFrame"]],["impl Send for OwnedFrame",1,["tests::softnpu::OwnedFrame"]],["impl<const R: usize, const N: usize, const F: usize> Send for OuterPhy<R, N, F>"]], +"vlan_switch":[["impl Send for ddm_h",1,["vlan_switch::ddm_h"]],["impl Send for egress_metadata_t",1,["vlan_switch::egress_metadata_t"]],["impl Send for udp_h",1,["vlan_switch::udp_h"]],["impl Send for ddm_element_t",1,["vlan_switch::ddm_element_t"]],["impl Send for ingress_metadata_t",1,["vlan_switch::ingress_metadata_t"]],["impl Send for tcp_h",1,["vlan_switch::tcp_h"]],["impl Send for vlan_h",1,["vlan_switch::vlan_h"]],["impl Send for ipv4_h",1,["vlan_switch::ipv4_h"]],["impl Send for ipv6_h",1,["vlan_switch::ipv6_h"]],["impl Send for icmp_h",1,["vlan_switch::icmp_h"]],["impl Send for geneve_h",1,["vlan_switch::geneve_h"]],["impl Send for arp_h",1,["vlan_switch::arp_h"]],["impl Send for headers_t",1,["vlan_switch::headers_t"]],["impl Send for ethernet_h",1,["vlan_switch::ethernet_h"]],["impl Send for sidecar_h",1,["vlan_switch::sidecar_h"]],["impl Send for main_pipeline"]], +"x4c":[["impl Send for Opts",1,["x4c::Opts"]],["impl Send for Target",1,["x4c::Target"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.StructuralPartialEq.js b/trait.impl/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 00000000..15d30bae --- /dev/null +++ b/trait.impl/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,4 @@ +(function() {var implementors = { +"p4":[["impl StructuralPartialEq for DeclarationInfo"],["impl StructuralPartialEq for Level"],["impl StructuralPartialEq for Direction"],["impl StructuralPartialEq for BinOp"],["impl StructuralPartialEq for Type"],["impl StructuralPartialEq for Kind"],["impl StructuralPartialEq for Token"]], +"p4rs":[["impl StructuralPartialEq for BigUintKey"],["impl StructuralPartialEq for Prefix"],["impl StructuralPartialEq for Ternary"],["impl StructuralPartialEq for Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Sync.js b/trait.impl/core/marker/trait.Sync.js new file mode 100644 index 00000000..b1099072 --- /dev/null +++ b/trait.impl/core/marker/trait.Sync.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"hello_world":[["impl Sync for headers_t",1,["hello_world::headers_t"]],["impl Sync for ethernet_h",1,["hello_world::ethernet_h"]],["impl Sync for egress_metadata_t",1,["hello_world::egress_metadata_t"]],["impl Sync for ingress_metadata_t",1,["hello_world::ingress_metadata_t"]],["impl !Sync for main_pipeline",1,["hello_world::main_pipeline"]]], +"p4":[["impl Sync for AST",1,["p4::ast::AST"]],["impl<'a> Sync for UserDefinedType<'a>",1,["p4::ast::UserDefinedType"]],["impl Sync for PackageInstance",1,["p4::ast::PackageInstance"]],["impl Sync for Package",1,["p4::ast::Package"]],["impl Sync for PackageParameter",1,["p4::ast::PackageParameter"]],["impl Sync for Type",1,["p4::ast::Type"]],["impl Sync for Typedef",1,["p4::ast::Typedef"]],["impl Sync for Constant",1,["p4::ast::Constant"]],["impl Sync for Variable",1,["p4::ast::Variable"]],["impl Sync for Expression",1,["p4::ast::Expression"]],["impl Sync for ExpressionKind",1,["p4::ast::ExpressionKind"]],["impl Sync for BinOp",1,["p4::ast::BinOp"]],["impl Sync for Header",1,["p4::ast::Header"]],["impl Sync for HeaderMember",1,["p4::ast::HeaderMember"]],["impl Sync for Struct",1,["p4::ast::Struct"]],["impl Sync for StructMember",1,["p4::ast::StructMember"]],["impl Sync for Control",1,["p4::ast::Control"]],["impl Sync for Parser",1,["p4::ast::Parser"]],["impl Sync for ControlParameter",1,["p4::ast::ControlParameter"]],["impl Sync for Direction",1,["p4::ast::Direction"]],["impl Sync for StatementBlock",1,["p4::ast::StatementBlock"]],["impl Sync for Action",1,["p4::ast::Action"]],["impl Sync for ActionParameter",1,["p4::ast::ActionParameter"]],["impl Sync for Table",1,["p4::ast::Table"]],["impl Sync for ConstTableEntry",1,["p4::ast::ConstTableEntry"]],["impl Sync for KeySetElement",1,["p4::ast::KeySetElement"]],["impl Sync for KeySetElementValue",1,["p4::ast::KeySetElementValue"]],["impl Sync for ActionRef",1,["p4::ast::ActionRef"]],["impl Sync for MatchKind",1,["p4::ast::MatchKind"]],["impl Sync for Statement",1,["p4::ast::Statement"]],["impl Sync for IfBlock",1,["p4::ast::IfBlock"]],["impl Sync for ElseIfBlock",1,["p4::ast::ElseIfBlock"]],["impl Sync for Call",1,["p4::ast::Call"]],["impl Sync for Lvalue",1,["p4::ast::Lvalue"]],["impl Sync for State",1,["p4::ast::State"]],["impl Sync for Transition",1,["p4::ast::Transition"]],["impl Sync for Select",1,["p4::ast::Select"]],["impl Sync for SelectElement",1,["p4::ast::SelectElement"]],["impl Sync for Extern",1,["p4::ast::Extern"]],["impl Sync for ExternMethod",1,["p4::ast::ExternMethod"]],["impl Sync for DeclarationInfo",1,["p4::ast::DeclarationInfo"]],["impl Sync for NameInfo",1,["p4::ast::NameInfo"]],["impl Sync for Diagnostic",1,["p4::check::Diagnostic"]],["impl Sync for Level",1,["p4::check::Level"]],["impl Sync for Diagnostics",1,["p4::check::Diagnostics"]],["impl Sync for ControlChecker",1,["p4::check::ControlChecker"]],["impl<'a> Sync for ApplyCallChecker<'a>",1,["p4::check::ApplyCallChecker"]],["impl Sync for ParserChecker",1,["p4::check::ParserChecker"]],["impl Sync for StructChecker",1,["p4::check::StructChecker"]],["impl Sync for HeaderChecker",1,["p4::check::HeaderChecker"]],["impl Sync for ExpressionTypeChecker",1,["p4::check::ExpressionTypeChecker"]],["impl Sync for SemanticError",1,["p4::error::SemanticError"]],["impl Sync for ParserError",1,["p4::error::ParserError"]],["impl Sync for TokenError",1,["p4::error::TokenError"]],["impl Sync for Error",1,["p4::error::Error"]],["impl Sync for PreprocessorError",1,["p4::error::PreprocessorError"]],["impl Sync for Hlir",1,["p4::hlir::Hlir"]],["impl<'a> Sync for HlirGenerator<'a>",1,["p4::hlir::HlirGenerator"]],["impl Sync for Kind",1,["p4::lexer::Kind"]],["impl Sync for Token",1,["p4::lexer::Token"]],["impl<'a> Sync for Lexer<'a>",1,["p4::lexer::Lexer"]],["impl<'a> Sync for Parser<'a>",1,["p4::parser::Parser"]],["impl<'a, 'b> Sync for GlobalParser<'a, 'b>",1,["p4::parser::GlobalParser"]],["impl<'a, 'b> Sync for ControlParser<'a, 'b>",1,["p4::parser::ControlParser"]],["impl<'a, 'b> Sync for ActionParser<'a, 'b>",1,["p4::parser::ActionParser"]],["impl<'a, 'b> Sync for TableParser<'a, 'b>",1,["p4::parser::TableParser"]],["impl<'a, 'b> Sync for StatementParser<'a, 'b>",1,["p4::parser::StatementParser"]],["impl<'a, 'b> Sync for IfElseParser<'a, 'b>",1,["p4::parser::IfElseParser"]],["impl<'a, 'b> Sync for ExpressionParser<'a, 'b>",1,["p4::parser::ExpressionParser"]],["impl<'a, 'b> Sync for ParserParser<'a, 'b>",1,["p4::parser::ParserParser"]],["impl<'a, 'b> Sync for StateParser<'a, 'b>",1,["p4::parser::StateParser"]],["impl<'a, 'b> Sync for SelectParser<'a, 'b>",1,["p4::parser::SelectParser"]],["impl Sync for PreprocessorResult",1,["p4::preprocessor::PreprocessorResult"]],["impl Sync for PreprocessorElements",1,["p4::preprocessor::PreprocessorElements"]]], +"p4_macro_test":[["impl Sync for ethernet_t",1,["p4_macro_test::ethernet_t"]],["impl Sync for headers_t",1,["p4_macro_test::headers_t"]]], +"p4_rust":[["impl Sync for Settings",1,["p4_rust::Settings"]],["impl Sync for Sanitizer",1,["p4_rust::Sanitizer"]]], +"p4rs":[["impl Sync for TryFromSliceError",1,["p4rs::error::TryFromSliceError"]],["impl Sync for Csum",1,["p4rs::checksum::Csum"]],["impl Sync for Checksum",1,["p4rs::externs::Checksum"]],["impl Sync for BigUintKey",1,["p4rs::table::BigUintKey"]],["impl Sync for Key",1,["p4rs::table::Key"]],["impl Sync for Ternary",1,["p4rs::table::Ternary"]],["impl Sync for Prefix",1,["p4rs::table::Prefix"]],["impl<const D: usize, A> Sync for Table<D, A>
where\n A: Sync,
",1,["p4rs::table::Table"]],["impl<const D: usize, A> Sync for TableEntry<D, A>
where\n A: Sync,
",1,["p4rs::table::TableEntry"]],["impl<'a, const N: usize> Sync for Bit<'a, N>",1,["p4rs::Bit"]],["impl<'a> Sync for packet_in<'a>",1,["p4rs::packet_in"]],["impl<'a> Sync for packet_out<'a>",1,["p4rs::packet_out"]],["impl Sync for TableEntry",1,["p4rs::TableEntry"]],["impl Sync for AlignedU128",1,["p4rs::AlignedU128"]]], +"sidecar_lite":[["impl Sync for tcp_h",1,["sidecar_lite::tcp_h"]],["impl Sync for ddm_h",1,["sidecar_lite::ddm_h"]],["impl Sync for sidecar_h",1,["sidecar_lite::sidecar_h"]],["impl Sync for vlan_h",1,["sidecar_lite::vlan_h"]],["impl Sync for ddm_element_t",1,["sidecar_lite::ddm_element_t"]],["impl Sync for ingress_metadata_t",1,["sidecar_lite::ingress_metadata_t"]],["impl Sync for ipv6_h",1,["sidecar_lite::ipv6_h"]],["impl Sync for ipv4_h",1,["sidecar_lite::ipv4_h"]],["impl Sync for icmp_h",1,["sidecar_lite::icmp_h"]],["impl Sync for ethernet_h",1,["sidecar_lite::ethernet_h"]],["impl Sync for arp_h",1,["sidecar_lite::arp_h"]],["impl Sync for headers_t",1,["sidecar_lite::headers_t"]],["impl Sync for egress_metadata_t",1,["sidecar_lite::egress_metadata_t"]],["impl Sync for geneve_h",1,["sidecar_lite::geneve_h"]],["impl Sync for udp_h",1,["sidecar_lite::udp_h"]],["impl !Sync for main_pipeline",1,["sidecar_lite::main_pipeline"]]], +"tests":[["impl<P> !Sync for SoftNpu<P>",1,["tests::softnpu::SoftNpu"]],["impl<const R: usize, const N: usize, const F: usize> !Sync for InnerPhy<R, N, F>",1,["tests::softnpu::InnerPhy"]],["impl<const R: usize, const N: usize, const F: usize> Sync for Interface6<R, N, F>",1,["tests::softnpu::Interface6"]],["impl<const R: usize, const N: usize, const F: usize> Sync for Interface4<R, N, F>",1,["tests::softnpu::Interface4"]],["impl<'a> Sync for TxFrame<'a>",1,["tests::softnpu::TxFrame"]],["impl<'a> Sync for RxFrame<'a>",1,["tests::softnpu::RxFrame"]],["impl Sync for OwnedFrame",1,["tests::softnpu::OwnedFrame"]],["impl<const R: usize, const N: usize, const F: usize> Sync for OuterPhy<R, N, F>"]], +"vlan_switch":[["impl Sync for ddm_h",1,["vlan_switch::ddm_h"]],["impl Sync for egress_metadata_t",1,["vlan_switch::egress_metadata_t"]],["impl Sync for udp_h",1,["vlan_switch::udp_h"]],["impl Sync for ddm_element_t",1,["vlan_switch::ddm_element_t"]],["impl Sync for ingress_metadata_t",1,["vlan_switch::ingress_metadata_t"]],["impl Sync for tcp_h",1,["vlan_switch::tcp_h"]],["impl Sync for vlan_h",1,["vlan_switch::vlan_h"]],["impl Sync for ipv4_h",1,["vlan_switch::ipv4_h"]],["impl Sync for ipv6_h",1,["vlan_switch::ipv6_h"]],["impl Sync for icmp_h",1,["vlan_switch::icmp_h"]],["impl Sync for geneve_h",1,["vlan_switch::geneve_h"]],["impl Sync for arp_h",1,["vlan_switch::arp_h"]],["impl Sync for headers_t",1,["vlan_switch::headers_t"]],["impl Sync for ethernet_h",1,["vlan_switch::ethernet_h"]],["impl Sync for sidecar_h",1,["vlan_switch::sidecar_h"]],["impl !Sync for main_pipeline",1,["vlan_switch::main_pipeline"]]], +"x4c":[["impl Sync for Opts",1,["x4c::Opts"]],["impl Sync for Target",1,["x4c::Target"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/marker/trait.Unpin.js b/trait.impl/core/marker/trait.Unpin.js new file mode 100644 index 00000000..51d751d5 --- /dev/null +++ b/trait.impl/core/marker/trait.Unpin.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"hello_world":[["impl Unpin for headers_t",1,["hello_world::headers_t"]],["impl Unpin for ethernet_h",1,["hello_world::ethernet_h"]],["impl Unpin for egress_metadata_t",1,["hello_world::egress_metadata_t"]],["impl Unpin for ingress_metadata_t",1,["hello_world::ingress_metadata_t"]],["impl Unpin for main_pipeline",1,["hello_world::main_pipeline"]]], +"p4":[["impl Unpin for AST",1,["p4::ast::AST"]],["impl<'a> Unpin for UserDefinedType<'a>",1,["p4::ast::UserDefinedType"]],["impl Unpin for PackageInstance",1,["p4::ast::PackageInstance"]],["impl Unpin for Package",1,["p4::ast::Package"]],["impl Unpin for PackageParameter",1,["p4::ast::PackageParameter"]],["impl Unpin for Type",1,["p4::ast::Type"]],["impl Unpin for Typedef",1,["p4::ast::Typedef"]],["impl Unpin for Constant",1,["p4::ast::Constant"]],["impl Unpin for Variable",1,["p4::ast::Variable"]],["impl Unpin for Expression",1,["p4::ast::Expression"]],["impl Unpin for ExpressionKind",1,["p4::ast::ExpressionKind"]],["impl Unpin for BinOp",1,["p4::ast::BinOp"]],["impl Unpin for Header",1,["p4::ast::Header"]],["impl Unpin for HeaderMember",1,["p4::ast::HeaderMember"]],["impl Unpin for Struct",1,["p4::ast::Struct"]],["impl Unpin for StructMember",1,["p4::ast::StructMember"]],["impl Unpin for Control",1,["p4::ast::Control"]],["impl Unpin for Parser",1,["p4::ast::Parser"]],["impl Unpin for ControlParameter",1,["p4::ast::ControlParameter"]],["impl Unpin for Direction",1,["p4::ast::Direction"]],["impl Unpin for StatementBlock",1,["p4::ast::StatementBlock"]],["impl Unpin for Action",1,["p4::ast::Action"]],["impl Unpin for ActionParameter",1,["p4::ast::ActionParameter"]],["impl Unpin for Table",1,["p4::ast::Table"]],["impl Unpin for ConstTableEntry",1,["p4::ast::ConstTableEntry"]],["impl Unpin for KeySetElement",1,["p4::ast::KeySetElement"]],["impl Unpin for KeySetElementValue",1,["p4::ast::KeySetElementValue"]],["impl Unpin for ActionRef",1,["p4::ast::ActionRef"]],["impl Unpin for MatchKind",1,["p4::ast::MatchKind"]],["impl Unpin for Statement",1,["p4::ast::Statement"]],["impl Unpin for IfBlock",1,["p4::ast::IfBlock"]],["impl Unpin for ElseIfBlock",1,["p4::ast::ElseIfBlock"]],["impl Unpin for Call",1,["p4::ast::Call"]],["impl Unpin for Lvalue",1,["p4::ast::Lvalue"]],["impl Unpin for State",1,["p4::ast::State"]],["impl Unpin for Transition",1,["p4::ast::Transition"]],["impl Unpin for Select",1,["p4::ast::Select"]],["impl Unpin for SelectElement",1,["p4::ast::SelectElement"]],["impl Unpin for Extern",1,["p4::ast::Extern"]],["impl Unpin for ExternMethod",1,["p4::ast::ExternMethod"]],["impl Unpin for DeclarationInfo",1,["p4::ast::DeclarationInfo"]],["impl Unpin for NameInfo",1,["p4::ast::NameInfo"]],["impl Unpin for Diagnostic",1,["p4::check::Diagnostic"]],["impl Unpin for Level",1,["p4::check::Level"]],["impl Unpin for Diagnostics",1,["p4::check::Diagnostics"]],["impl Unpin for ControlChecker",1,["p4::check::ControlChecker"]],["impl<'a> Unpin for ApplyCallChecker<'a>",1,["p4::check::ApplyCallChecker"]],["impl Unpin for ParserChecker",1,["p4::check::ParserChecker"]],["impl Unpin for StructChecker",1,["p4::check::StructChecker"]],["impl Unpin for HeaderChecker",1,["p4::check::HeaderChecker"]],["impl Unpin for ExpressionTypeChecker",1,["p4::check::ExpressionTypeChecker"]],["impl Unpin for SemanticError",1,["p4::error::SemanticError"]],["impl Unpin for ParserError",1,["p4::error::ParserError"]],["impl Unpin for TokenError",1,["p4::error::TokenError"]],["impl Unpin for Error",1,["p4::error::Error"]],["impl Unpin for PreprocessorError",1,["p4::error::PreprocessorError"]],["impl Unpin for Hlir",1,["p4::hlir::Hlir"]],["impl<'a> Unpin for HlirGenerator<'a>",1,["p4::hlir::HlirGenerator"]],["impl Unpin for Kind",1,["p4::lexer::Kind"]],["impl Unpin for Token",1,["p4::lexer::Token"]],["impl<'a> Unpin for Lexer<'a>",1,["p4::lexer::Lexer"]],["impl<'a> Unpin for Parser<'a>",1,["p4::parser::Parser"]],["impl<'a, 'b> Unpin for GlobalParser<'a, 'b>",1,["p4::parser::GlobalParser"]],["impl<'a, 'b> Unpin for ControlParser<'a, 'b>",1,["p4::parser::ControlParser"]],["impl<'a, 'b> Unpin for ActionParser<'a, 'b>",1,["p4::parser::ActionParser"]],["impl<'a, 'b> Unpin for TableParser<'a, 'b>",1,["p4::parser::TableParser"]],["impl<'a, 'b> Unpin for StatementParser<'a, 'b>",1,["p4::parser::StatementParser"]],["impl<'a, 'b> Unpin for IfElseParser<'a, 'b>",1,["p4::parser::IfElseParser"]],["impl<'a, 'b> Unpin for ExpressionParser<'a, 'b>",1,["p4::parser::ExpressionParser"]],["impl<'a, 'b> Unpin for ParserParser<'a, 'b>",1,["p4::parser::ParserParser"]],["impl<'a, 'b> Unpin for StateParser<'a, 'b>",1,["p4::parser::StateParser"]],["impl<'a, 'b> Unpin for SelectParser<'a, 'b>",1,["p4::parser::SelectParser"]],["impl Unpin for PreprocessorResult",1,["p4::preprocessor::PreprocessorResult"]],["impl Unpin for PreprocessorElements",1,["p4::preprocessor::PreprocessorElements"]]], +"p4_macro_test":[["impl Unpin for ethernet_t",1,["p4_macro_test::ethernet_t"]],["impl Unpin for headers_t",1,["p4_macro_test::headers_t"]]], +"p4_rust":[["impl Unpin for Settings",1,["p4_rust::Settings"]],["impl Unpin for Sanitizer",1,["p4_rust::Sanitizer"]]], +"p4rs":[["impl Unpin for TryFromSliceError",1,["p4rs::error::TryFromSliceError"]],["impl Unpin for Csum",1,["p4rs::checksum::Csum"]],["impl Unpin for Checksum",1,["p4rs::externs::Checksum"]],["impl Unpin for BigUintKey",1,["p4rs::table::BigUintKey"]],["impl Unpin for Key",1,["p4rs::table::Key"]],["impl Unpin for Ternary",1,["p4rs::table::Ternary"]],["impl Unpin for Prefix",1,["p4rs::table::Prefix"]],["impl<const D: usize, A> Unpin for Table<D, A>
where\n A: Unpin,
",1,["p4rs::table::Table"]],["impl<const D: usize, A> Unpin for TableEntry<D, A>
where\n A: Unpin,
",1,["p4rs::table::TableEntry"]],["impl<'a, const N: usize> Unpin for Bit<'a, N>",1,["p4rs::Bit"]],["impl<'a> Unpin for packet_in<'a>",1,["p4rs::packet_in"]],["impl<'a> Unpin for packet_out<'a>",1,["p4rs::packet_out"]],["impl Unpin for TableEntry",1,["p4rs::TableEntry"]],["impl Unpin for AlignedU128",1,["p4rs::AlignedU128"]]], +"sidecar_lite":[["impl Unpin for tcp_h",1,["sidecar_lite::tcp_h"]],["impl Unpin for ddm_h",1,["sidecar_lite::ddm_h"]],["impl Unpin for sidecar_h",1,["sidecar_lite::sidecar_h"]],["impl Unpin for vlan_h",1,["sidecar_lite::vlan_h"]],["impl Unpin for ddm_element_t",1,["sidecar_lite::ddm_element_t"]],["impl Unpin for ingress_metadata_t",1,["sidecar_lite::ingress_metadata_t"]],["impl Unpin for ipv6_h",1,["sidecar_lite::ipv6_h"]],["impl Unpin for ipv4_h",1,["sidecar_lite::ipv4_h"]],["impl Unpin for icmp_h",1,["sidecar_lite::icmp_h"]],["impl Unpin for ethernet_h",1,["sidecar_lite::ethernet_h"]],["impl Unpin for arp_h",1,["sidecar_lite::arp_h"]],["impl Unpin for headers_t",1,["sidecar_lite::headers_t"]],["impl Unpin for egress_metadata_t",1,["sidecar_lite::egress_metadata_t"]],["impl Unpin for geneve_h",1,["sidecar_lite::geneve_h"]],["impl Unpin for udp_h",1,["sidecar_lite::udp_h"]],["impl Unpin for main_pipeline",1,["sidecar_lite::main_pipeline"]]], +"tests":[["impl<P> Unpin for SoftNpu<P>
where\n P: Unpin,
",1,["tests::softnpu::SoftNpu"]],["impl<const R: usize, const N: usize, const F: usize> Unpin for InnerPhy<R, N, F>",1,["tests::softnpu::InnerPhy"]],["impl<const R: usize, const N: usize, const F: usize> Unpin for OuterPhy<R, N, F>",1,["tests::softnpu::OuterPhy"]],["impl<const R: usize, const N: usize, const F: usize> Unpin for Interface6<R, N, F>",1,["tests::softnpu::Interface6"]],["impl<const R: usize, const N: usize, const F: usize> Unpin for Interface4<R, N, F>",1,["tests::softnpu::Interface4"]],["impl<'a> Unpin for TxFrame<'a>",1,["tests::softnpu::TxFrame"]],["impl<'a> Unpin for RxFrame<'a>",1,["tests::softnpu::RxFrame"]],["impl Unpin for OwnedFrame",1,["tests::softnpu::OwnedFrame"]]], +"vlan_switch":[["impl Unpin for ddm_h",1,["vlan_switch::ddm_h"]],["impl Unpin for egress_metadata_t",1,["vlan_switch::egress_metadata_t"]],["impl Unpin for udp_h",1,["vlan_switch::udp_h"]],["impl Unpin for ddm_element_t",1,["vlan_switch::ddm_element_t"]],["impl Unpin for ingress_metadata_t",1,["vlan_switch::ingress_metadata_t"]],["impl Unpin for tcp_h",1,["vlan_switch::tcp_h"]],["impl Unpin for vlan_h",1,["vlan_switch::vlan_h"]],["impl Unpin for ipv4_h",1,["vlan_switch::ipv4_h"]],["impl Unpin for ipv6_h",1,["vlan_switch::ipv6_h"]],["impl Unpin for icmp_h",1,["vlan_switch::icmp_h"]],["impl Unpin for geneve_h",1,["vlan_switch::geneve_h"]],["impl Unpin for arp_h",1,["vlan_switch::arp_h"]],["impl Unpin for headers_t",1,["vlan_switch::headers_t"]],["impl Unpin for ethernet_h",1,["vlan_switch::ethernet_h"]],["impl Unpin for sidecar_h",1,["vlan_switch::sidecar_h"]],["impl Unpin for main_pipeline",1,["vlan_switch::main_pipeline"]]], +"x4c":[["impl Unpin for Opts",1,["x4c::Opts"]],["impl Unpin for Target",1,["x4c::Target"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 00000000..f7d7dfcd --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"hello_world":[["impl RefUnwindSafe for headers_t",1,["hello_world::headers_t"]],["impl RefUnwindSafe for ethernet_h",1,["hello_world::ethernet_h"]],["impl RefUnwindSafe for egress_metadata_t",1,["hello_world::egress_metadata_t"]],["impl RefUnwindSafe for ingress_metadata_t",1,["hello_world::ingress_metadata_t"]],["impl !RefUnwindSafe for main_pipeline",1,["hello_world::main_pipeline"]]], +"p4":[["impl RefUnwindSafe for AST",1,["p4::ast::AST"]],["impl<'a> RefUnwindSafe for UserDefinedType<'a>",1,["p4::ast::UserDefinedType"]],["impl RefUnwindSafe for PackageInstance",1,["p4::ast::PackageInstance"]],["impl RefUnwindSafe for Package",1,["p4::ast::Package"]],["impl RefUnwindSafe for PackageParameter",1,["p4::ast::PackageParameter"]],["impl RefUnwindSafe for Type",1,["p4::ast::Type"]],["impl RefUnwindSafe for Typedef",1,["p4::ast::Typedef"]],["impl RefUnwindSafe for Constant",1,["p4::ast::Constant"]],["impl RefUnwindSafe for Variable",1,["p4::ast::Variable"]],["impl RefUnwindSafe for Expression",1,["p4::ast::Expression"]],["impl RefUnwindSafe for ExpressionKind",1,["p4::ast::ExpressionKind"]],["impl RefUnwindSafe for BinOp",1,["p4::ast::BinOp"]],["impl RefUnwindSafe for Header",1,["p4::ast::Header"]],["impl RefUnwindSafe for HeaderMember",1,["p4::ast::HeaderMember"]],["impl RefUnwindSafe for Struct",1,["p4::ast::Struct"]],["impl RefUnwindSafe for StructMember",1,["p4::ast::StructMember"]],["impl RefUnwindSafe for Control",1,["p4::ast::Control"]],["impl RefUnwindSafe for Parser",1,["p4::ast::Parser"]],["impl RefUnwindSafe for ControlParameter",1,["p4::ast::ControlParameter"]],["impl RefUnwindSafe for Direction",1,["p4::ast::Direction"]],["impl RefUnwindSafe for StatementBlock",1,["p4::ast::StatementBlock"]],["impl RefUnwindSafe for Action",1,["p4::ast::Action"]],["impl RefUnwindSafe for ActionParameter",1,["p4::ast::ActionParameter"]],["impl RefUnwindSafe for Table",1,["p4::ast::Table"]],["impl RefUnwindSafe for ConstTableEntry",1,["p4::ast::ConstTableEntry"]],["impl RefUnwindSafe for KeySetElement",1,["p4::ast::KeySetElement"]],["impl RefUnwindSafe for KeySetElementValue",1,["p4::ast::KeySetElementValue"]],["impl RefUnwindSafe for ActionRef",1,["p4::ast::ActionRef"]],["impl RefUnwindSafe for MatchKind",1,["p4::ast::MatchKind"]],["impl RefUnwindSafe for Statement",1,["p4::ast::Statement"]],["impl RefUnwindSafe for IfBlock",1,["p4::ast::IfBlock"]],["impl RefUnwindSafe for ElseIfBlock",1,["p4::ast::ElseIfBlock"]],["impl RefUnwindSafe for Call",1,["p4::ast::Call"]],["impl RefUnwindSafe for Lvalue",1,["p4::ast::Lvalue"]],["impl RefUnwindSafe for State",1,["p4::ast::State"]],["impl RefUnwindSafe for Transition",1,["p4::ast::Transition"]],["impl RefUnwindSafe for Select",1,["p4::ast::Select"]],["impl RefUnwindSafe for SelectElement",1,["p4::ast::SelectElement"]],["impl RefUnwindSafe for Extern",1,["p4::ast::Extern"]],["impl RefUnwindSafe for ExternMethod",1,["p4::ast::ExternMethod"]],["impl RefUnwindSafe for DeclarationInfo",1,["p4::ast::DeclarationInfo"]],["impl RefUnwindSafe for NameInfo",1,["p4::ast::NameInfo"]],["impl RefUnwindSafe for Diagnostic",1,["p4::check::Diagnostic"]],["impl RefUnwindSafe for Level",1,["p4::check::Level"]],["impl RefUnwindSafe for Diagnostics",1,["p4::check::Diagnostics"]],["impl RefUnwindSafe for ControlChecker",1,["p4::check::ControlChecker"]],["impl<'a> RefUnwindSafe for ApplyCallChecker<'a>",1,["p4::check::ApplyCallChecker"]],["impl RefUnwindSafe for ParserChecker",1,["p4::check::ParserChecker"]],["impl RefUnwindSafe for StructChecker",1,["p4::check::StructChecker"]],["impl RefUnwindSafe for HeaderChecker",1,["p4::check::HeaderChecker"]],["impl RefUnwindSafe for ExpressionTypeChecker",1,["p4::check::ExpressionTypeChecker"]],["impl RefUnwindSafe for SemanticError",1,["p4::error::SemanticError"]],["impl RefUnwindSafe for ParserError",1,["p4::error::ParserError"]],["impl RefUnwindSafe for TokenError",1,["p4::error::TokenError"]],["impl RefUnwindSafe for Error",1,["p4::error::Error"]],["impl RefUnwindSafe for PreprocessorError",1,["p4::error::PreprocessorError"]],["impl RefUnwindSafe for Hlir",1,["p4::hlir::Hlir"]],["impl<'a> RefUnwindSafe for HlirGenerator<'a>",1,["p4::hlir::HlirGenerator"]],["impl RefUnwindSafe for Kind",1,["p4::lexer::Kind"]],["impl RefUnwindSafe for Token",1,["p4::lexer::Token"]],["impl<'a> RefUnwindSafe for Lexer<'a>",1,["p4::lexer::Lexer"]],["impl<'a> RefUnwindSafe for Parser<'a>",1,["p4::parser::Parser"]],["impl<'a, 'b> RefUnwindSafe for GlobalParser<'a, 'b>",1,["p4::parser::GlobalParser"]],["impl<'a, 'b> RefUnwindSafe for ControlParser<'a, 'b>",1,["p4::parser::ControlParser"]],["impl<'a, 'b> RefUnwindSafe for ActionParser<'a, 'b>",1,["p4::parser::ActionParser"]],["impl<'a, 'b> RefUnwindSafe for TableParser<'a, 'b>",1,["p4::parser::TableParser"]],["impl<'a, 'b> RefUnwindSafe for StatementParser<'a, 'b>",1,["p4::parser::StatementParser"]],["impl<'a, 'b> RefUnwindSafe for IfElseParser<'a, 'b>",1,["p4::parser::IfElseParser"]],["impl<'a, 'b> RefUnwindSafe for ExpressionParser<'a, 'b>",1,["p4::parser::ExpressionParser"]],["impl<'a, 'b> RefUnwindSafe for ParserParser<'a, 'b>",1,["p4::parser::ParserParser"]],["impl<'a, 'b> RefUnwindSafe for StateParser<'a, 'b>",1,["p4::parser::StateParser"]],["impl<'a, 'b> RefUnwindSafe for SelectParser<'a, 'b>",1,["p4::parser::SelectParser"]],["impl RefUnwindSafe for PreprocessorResult",1,["p4::preprocessor::PreprocessorResult"]],["impl RefUnwindSafe for PreprocessorElements",1,["p4::preprocessor::PreprocessorElements"]]], +"p4_macro_test":[["impl RefUnwindSafe for ethernet_t",1,["p4_macro_test::ethernet_t"]],["impl RefUnwindSafe for headers_t",1,["p4_macro_test::headers_t"]]], +"p4_rust":[["impl RefUnwindSafe for Settings",1,["p4_rust::Settings"]],["impl RefUnwindSafe for Sanitizer",1,["p4_rust::Sanitizer"]]], +"p4rs":[["impl RefUnwindSafe for TryFromSliceError",1,["p4rs::error::TryFromSliceError"]],["impl RefUnwindSafe for Csum",1,["p4rs::checksum::Csum"]],["impl RefUnwindSafe for Checksum",1,["p4rs::externs::Checksum"]],["impl RefUnwindSafe for BigUintKey",1,["p4rs::table::BigUintKey"]],["impl RefUnwindSafe for Key",1,["p4rs::table::Key"]],["impl RefUnwindSafe for Ternary",1,["p4rs::table::Ternary"]],["impl RefUnwindSafe for Prefix",1,["p4rs::table::Prefix"]],["impl<const D: usize, A> RefUnwindSafe for Table<D, A>
where\n A: RefUnwindSafe,
",1,["p4rs::table::Table"]],["impl<const D: usize, A> RefUnwindSafe for TableEntry<D, A>
where\n A: RefUnwindSafe,
",1,["p4rs::table::TableEntry"]],["impl<'a, const N: usize> RefUnwindSafe for Bit<'a, N>",1,["p4rs::Bit"]],["impl<'a> RefUnwindSafe for packet_in<'a>",1,["p4rs::packet_in"]],["impl<'a> RefUnwindSafe for packet_out<'a>",1,["p4rs::packet_out"]],["impl RefUnwindSafe for TableEntry",1,["p4rs::TableEntry"]],["impl RefUnwindSafe for AlignedU128",1,["p4rs::AlignedU128"]]], +"sidecar_lite":[["impl RefUnwindSafe for tcp_h",1,["sidecar_lite::tcp_h"]],["impl RefUnwindSafe for ddm_h",1,["sidecar_lite::ddm_h"]],["impl RefUnwindSafe for sidecar_h",1,["sidecar_lite::sidecar_h"]],["impl RefUnwindSafe for vlan_h",1,["sidecar_lite::vlan_h"]],["impl RefUnwindSafe for ddm_element_t",1,["sidecar_lite::ddm_element_t"]],["impl RefUnwindSafe for ingress_metadata_t",1,["sidecar_lite::ingress_metadata_t"]],["impl RefUnwindSafe for ipv6_h",1,["sidecar_lite::ipv6_h"]],["impl RefUnwindSafe for ipv4_h",1,["sidecar_lite::ipv4_h"]],["impl RefUnwindSafe for icmp_h",1,["sidecar_lite::icmp_h"]],["impl RefUnwindSafe for ethernet_h",1,["sidecar_lite::ethernet_h"]],["impl RefUnwindSafe for arp_h",1,["sidecar_lite::arp_h"]],["impl RefUnwindSafe for headers_t",1,["sidecar_lite::headers_t"]],["impl RefUnwindSafe for egress_metadata_t",1,["sidecar_lite::egress_metadata_t"]],["impl RefUnwindSafe for geneve_h",1,["sidecar_lite::geneve_h"]],["impl RefUnwindSafe for udp_h",1,["sidecar_lite::udp_h"]],["impl !RefUnwindSafe for main_pipeline",1,["sidecar_lite::main_pipeline"]]], +"tests":[["impl<P> !RefUnwindSafe for SoftNpu<P>",1,["tests::softnpu::SoftNpu"]],["impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for InnerPhy<R, N, F>",1,["tests::softnpu::InnerPhy"]],["impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for OuterPhy<R, N, F>",1,["tests::softnpu::OuterPhy"]],["impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for Interface6<R, N, F>",1,["tests::softnpu::Interface6"]],["impl<const R: usize, const N: usize, const F: usize> !RefUnwindSafe for Interface4<R, N, F>",1,["tests::softnpu::Interface4"]],["impl<'a> RefUnwindSafe for TxFrame<'a>",1,["tests::softnpu::TxFrame"]],["impl<'a> RefUnwindSafe for RxFrame<'a>",1,["tests::softnpu::RxFrame"]],["impl RefUnwindSafe for OwnedFrame",1,["tests::softnpu::OwnedFrame"]]], +"vlan_switch":[["impl RefUnwindSafe for ddm_h",1,["vlan_switch::ddm_h"]],["impl RefUnwindSafe for egress_metadata_t",1,["vlan_switch::egress_metadata_t"]],["impl RefUnwindSafe for udp_h",1,["vlan_switch::udp_h"]],["impl RefUnwindSafe for ddm_element_t",1,["vlan_switch::ddm_element_t"]],["impl RefUnwindSafe for ingress_metadata_t",1,["vlan_switch::ingress_metadata_t"]],["impl RefUnwindSafe for tcp_h",1,["vlan_switch::tcp_h"]],["impl RefUnwindSafe for vlan_h",1,["vlan_switch::vlan_h"]],["impl RefUnwindSafe for ipv4_h",1,["vlan_switch::ipv4_h"]],["impl RefUnwindSafe for ipv6_h",1,["vlan_switch::ipv6_h"]],["impl RefUnwindSafe for icmp_h",1,["vlan_switch::icmp_h"]],["impl RefUnwindSafe for geneve_h",1,["vlan_switch::geneve_h"]],["impl RefUnwindSafe for arp_h",1,["vlan_switch::arp_h"]],["impl RefUnwindSafe for headers_t",1,["vlan_switch::headers_t"]],["impl RefUnwindSafe for ethernet_h",1,["vlan_switch::ethernet_h"]],["impl RefUnwindSafe for sidecar_h",1,["vlan_switch::sidecar_h"]],["impl !RefUnwindSafe for main_pipeline",1,["vlan_switch::main_pipeline"]]], +"x4c":[["impl RefUnwindSafe for Opts",1,["x4c::Opts"]],["impl RefUnwindSafe for Target",1,["x4c::Target"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 00000000..e4d7f9aa --- /dev/null +++ b/trait.impl/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,11 @@ +(function() {var implementors = { +"hello_world":[["impl UnwindSafe for headers_t",1,["hello_world::headers_t"]],["impl UnwindSafe for ethernet_h",1,["hello_world::ethernet_h"]],["impl UnwindSafe for egress_metadata_t",1,["hello_world::egress_metadata_t"]],["impl UnwindSafe for ingress_metadata_t",1,["hello_world::ingress_metadata_t"]],["impl !UnwindSafe for main_pipeline",1,["hello_world::main_pipeline"]]], +"p4":[["impl UnwindSafe for AST",1,["p4::ast::AST"]],["impl<'a> UnwindSafe for UserDefinedType<'a>",1,["p4::ast::UserDefinedType"]],["impl UnwindSafe for PackageInstance",1,["p4::ast::PackageInstance"]],["impl UnwindSafe for Package",1,["p4::ast::Package"]],["impl UnwindSafe for PackageParameter",1,["p4::ast::PackageParameter"]],["impl UnwindSafe for Type",1,["p4::ast::Type"]],["impl UnwindSafe for Typedef",1,["p4::ast::Typedef"]],["impl UnwindSafe for Constant",1,["p4::ast::Constant"]],["impl UnwindSafe for Variable",1,["p4::ast::Variable"]],["impl UnwindSafe for Expression",1,["p4::ast::Expression"]],["impl UnwindSafe for ExpressionKind",1,["p4::ast::ExpressionKind"]],["impl UnwindSafe for BinOp",1,["p4::ast::BinOp"]],["impl UnwindSafe for Header",1,["p4::ast::Header"]],["impl UnwindSafe for HeaderMember",1,["p4::ast::HeaderMember"]],["impl UnwindSafe for Struct",1,["p4::ast::Struct"]],["impl UnwindSafe for StructMember",1,["p4::ast::StructMember"]],["impl UnwindSafe for Control",1,["p4::ast::Control"]],["impl UnwindSafe for Parser",1,["p4::ast::Parser"]],["impl UnwindSafe for ControlParameter",1,["p4::ast::ControlParameter"]],["impl UnwindSafe for Direction",1,["p4::ast::Direction"]],["impl UnwindSafe for StatementBlock",1,["p4::ast::StatementBlock"]],["impl UnwindSafe for Action",1,["p4::ast::Action"]],["impl UnwindSafe for ActionParameter",1,["p4::ast::ActionParameter"]],["impl UnwindSafe for Table",1,["p4::ast::Table"]],["impl UnwindSafe for ConstTableEntry",1,["p4::ast::ConstTableEntry"]],["impl UnwindSafe for KeySetElement",1,["p4::ast::KeySetElement"]],["impl UnwindSafe for KeySetElementValue",1,["p4::ast::KeySetElementValue"]],["impl UnwindSafe for ActionRef",1,["p4::ast::ActionRef"]],["impl UnwindSafe for MatchKind",1,["p4::ast::MatchKind"]],["impl UnwindSafe for Statement",1,["p4::ast::Statement"]],["impl UnwindSafe for IfBlock",1,["p4::ast::IfBlock"]],["impl UnwindSafe for ElseIfBlock",1,["p4::ast::ElseIfBlock"]],["impl UnwindSafe for Call",1,["p4::ast::Call"]],["impl UnwindSafe for Lvalue",1,["p4::ast::Lvalue"]],["impl UnwindSafe for State",1,["p4::ast::State"]],["impl UnwindSafe for Transition",1,["p4::ast::Transition"]],["impl UnwindSafe for Select",1,["p4::ast::Select"]],["impl UnwindSafe for SelectElement",1,["p4::ast::SelectElement"]],["impl UnwindSafe for Extern",1,["p4::ast::Extern"]],["impl UnwindSafe for ExternMethod",1,["p4::ast::ExternMethod"]],["impl UnwindSafe for DeclarationInfo",1,["p4::ast::DeclarationInfo"]],["impl UnwindSafe for NameInfo",1,["p4::ast::NameInfo"]],["impl UnwindSafe for Diagnostic",1,["p4::check::Diagnostic"]],["impl UnwindSafe for Level",1,["p4::check::Level"]],["impl UnwindSafe for Diagnostics",1,["p4::check::Diagnostics"]],["impl UnwindSafe for ControlChecker",1,["p4::check::ControlChecker"]],["impl<'a> !UnwindSafe for ApplyCallChecker<'a>",1,["p4::check::ApplyCallChecker"]],["impl UnwindSafe for ParserChecker",1,["p4::check::ParserChecker"]],["impl UnwindSafe for StructChecker",1,["p4::check::StructChecker"]],["impl UnwindSafe for HeaderChecker",1,["p4::check::HeaderChecker"]],["impl UnwindSafe for ExpressionTypeChecker",1,["p4::check::ExpressionTypeChecker"]],["impl UnwindSafe for SemanticError",1,["p4::error::SemanticError"]],["impl UnwindSafe for ParserError",1,["p4::error::ParserError"]],["impl UnwindSafe for TokenError",1,["p4::error::TokenError"]],["impl UnwindSafe for Error",1,["p4::error::Error"]],["impl UnwindSafe for PreprocessorError",1,["p4::error::PreprocessorError"]],["impl UnwindSafe for Hlir",1,["p4::hlir::Hlir"]],["impl<'a> UnwindSafe for HlirGenerator<'a>",1,["p4::hlir::HlirGenerator"]],["impl UnwindSafe for Kind",1,["p4::lexer::Kind"]],["impl UnwindSafe for Token",1,["p4::lexer::Token"]],["impl<'a> UnwindSafe for Lexer<'a>",1,["p4::lexer::Lexer"]],["impl<'a> UnwindSafe for Parser<'a>",1,["p4::parser::Parser"]],["impl<'a, 'b> !UnwindSafe for GlobalParser<'a, 'b>",1,["p4::parser::GlobalParser"]],["impl<'a, 'b> !UnwindSafe for ControlParser<'a, 'b>",1,["p4::parser::ControlParser"]],["impl<'a, 'b> !UnwindSafe for ActionParser<'a, 'b>",1,["p4::parser::ActionParser"]],["impl<'a, 'b> !UnwindSafe for TableParser<'a, 'b>",1,["p4::parser::TableParser"]],["impl<'a, 'b> !UnwindSafe for StatementParser<'a, 'b>",1,["p4::parser::StatementParser"]],["impl<'a, 'b> !UnwindSafe for IfElseParser<'a, 'b>",1,["p4::parser::IfElseParser"]],["impl<'a, 'b> !UnwindSafe for ExpressionParser<'a, 'b>",1,["p4::parser::ExpressionParser"]],["impl<'a, 'b> !UnwindSafe for ParserParser<'a, 'b>",1,["p4::parser::ParserParser"]],["impl<'a, 'b> !UnwindSafe for StateParser<'a, 'b>",1,["p4::parser::StateParser"]],["impl<'a, 'b> !UnwindSafe for SelectParser<'a, 'b>",1,["p4::parser::SelectParser"]],["impl UnwindSafe for PreprocessorResult",1,["p4::preprocessor::PreprocessorResult"]],["impl UnwindSafe for PreprocessorElements",1,["p4::preprocessor::PreprocessorElements"]]], +"p4_macro_test":[["impl UnwindSafe for ethernet_t",1,["p4_macro_test::ethernet_t"]],["impl UnwindSafe for headers_t",1,["p4_macro_test::headers_t"]]], +"p4_rust":[["impl UnwindSafe for Settings",1,["p4_rust::Settings"]],["impl UnwindSafe for Sanitizer",1,["p4_rust::Sanitizer"]]], +"p4rs":[["impl UnwindSafe for TryFromSliceError",1,["p4rs::error::TryFromSliceError"]],["impl UnwindSafe for Csum",1,["p4rs::checksum::Csum"]],["impl UnwindSafe for Checksum",1,["p4rs::externs::Checksum"]],["impl UnwindSafe for BigUintKey",1,["p4rs::table::BigUintKey"]],["impl UnwindSafe for Key",1,["p4rs::table::Key"]],["impl UnwindSafe for Ternary",1,["p4rs::table::Ternary"]],["impl UnwindSafe for Prefix",1,["p4rs::table::Prefix"]],["impl<const D: usize, A> UnwindSafe for Table<D, A>
where\n A: UnwindSafe,
",1,["p4rs::table::Table"]],["impl<const D: usize, A> UnwindSafe for TableEntry<D, A>
where\n A: UnwindSafe,
",1,["p4rs::table::TableEntry"]],["impl<'a, const N: usize> UnwindSafe for Bit<'a, N>",1,["p4rs::Bit"]],["impl<'a> UnwindSafe for packet_in<'a>",1,["p4rs::packet_in"]],["impl<'a> UnwindSafe for packet_out<'a>",1,["p4rs::packet_out"]],["impl UnwindSafe for TableEntry",1,["p4rs::TableEntry"]],["impl UnwindSafe for AlignedU128",1,["p4rs::AlignedU128"]]], +"sidecar_lite":[["impl UnwindSafe for tcp_h",1,["sidecar_lite::tcp_h"]],["impl UnwindSafe for ddm_h",1,["sidecar_lite::ddm_h"]],["impl UnwindSafe for sidecar_h",1,["sidecar_lite::sidecar_h"]],["impl UnwindSafe for vlan_h",1,["sidecar_lite::vlan_h"]],["impl UnwindSafe for ddm_element_t",1,["sidecar_lite::ddm_element_t"]],["impl UnwindSafe for ingress_metadata_t",1,["sidecar_lite::ingress_metadata_t"]],["impl UnwindSafe for ipv6_h",1,["sidecar_lite::ipv6_h"]],["impl UnwindSafe for ipv4_h",1,["sidecar_lite::ipv4_h"]],["impl UnwindSafe for icmp_h",1,["sidecar_lite::icmp_h"]],["impl UnwindSafe for ethernet_h",1,["sidecar_lite::ethernet_h"]],["impl UnwindSafe for arp_h",1,["sidecar_lite::arp_h"]],["impl UnwindSafe for headers_t",1,["sidecar_lite::headers_t"]],["impl UnwindSafe for egress_metadata_t",1,["sidecar_lite::egress_metadata_t"]],["impl UnwindSafe for geneve_h",1,["sidecar_lite::geneve_h"]],["impl UnwindSafe for udp_h",1,["sidecar_lite::udp_h"]],["impl !UnwindSafe for main_pipeline",1,["sidecar_lite::main_pipeline"]]], +"tests":[["impl<P> !UnwindSafe for SoftNpu<P>",1,["tests::softnpu::SoftNpu"]],["impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for InnerPhy<R, N, F>",1,["tests::softnpu::InnerPhy"]],["impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for OuterPhy<R, N, F>",1,["tests::softnpu::OuterPhy"]],["impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for Interface6<R, N, F>",1,["tests::softnpu::Interface6"]],["impl<const R: usize, const N: usize, const F: usize> !UnwindSafe for Interface4<R, N, F>",1,["tests::softnpu::Interface4"]],["impl<'a> UnwindSafe for TxFrame<'a>",1,["tests::softnpu::TxFrame"]],["impl<'a> UnwindSafe for RxFrame<'a>",1,["tests::softnpu::RxFrame"]],["impl UnwindSafe for OwnedFrame",1,["tests::softnpu::OwnedFrame"]]], +"vlan_switch":[["impl UnwindSafe for ddm_h",1,["vlan_switch::ddm_h"]],["impl UnwindSafe for egress_metadata_t",1,["vlan_switch::egress_metadata_t"]],["impl UnwindSafe for udp_h",1,["vlan_switch::udp_h"]],["impl UnwindSafe for ddm_element_t",1,["vlan_switch::ddm_element_t"]],["impl UnwindSafe for ingress_metadata_t",1,["vlan_switch::ingress_metadata_t"]],["impl UnwindSafe for tcp_h",1,["vlan_switch::tcp_h"]],["impl UnwindSafe for vlan_h",1,["vlan_switch::vlan_h"]],["impl UnwindSafe for ipv4_h",1,["vlan_switch::ipv4_h"]],["impl UnwindSafe for ipv6_h",1,["vlan_switch::ipv6_h"]],["impl UnwindSafe for icmp_h",1,["vlan_switch::icmp_h"]],["impl UnwindSafe for geneve_h",1,["vlan_switch::geneve_h"]],["impl UnwindSafe for arp_h",1,["vlan_switch::arp_h"]],["impl UnwindSafe for headers_t",1,["vlan_switch::headers_t"]],["impl UnwindSafe for ethernet_h",1,["vlan_switch::ethernet_h"]],["impl UnwindSafe for sidecar_h",1,["vlan_switch::sidecar_h"]],["impl !UnwindSafe for main_pipeline",1,["vlan_switch::main_pipeline"]]], +"x4c":[["impl UnwindSafe for Opts",1,["x4c::Opts"]],["impl UnwindSafe for Target",1,["x4c::Target"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/p4/ast/trait.MutVisitor.js b/trait.impl/p4/ast/trait.MutVisitor.js new file mode 100644 index 00000000..4f6da615 --- /dev/null +++ b/trait.impl/p4/ast/trait.MutVisitor.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4_rust":[["impl MutVisitor for Sanitizer"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/p4/ast/trait.VisitorMut.js b/trait.impl/p4/ast/trait.VisitorMut.js new file mode 100644 index 00000000..6a911aa2 --- /dev/null +++ b/trait.impl/p4/ast/trait.VisitorMut.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/p4rs/checksum/trait.Checksum.js b/trait.impl/p4rs/checksum/trait.Checksum.js new file mode 100644 index 00000000..edd3eda7 --- /dev/null +++ b/trait.impl/p4rs/checksum/trait.Checksum.js @@ -0,0 +1,7 @@ +(function() {var implementors = { +"hello_world":[["impl Checksum for ethernet_h"]], +"p4_macro_test":[["impl Checksum for ethernet_t"]], +"p4rs":[], +"sidecar_lite":[["impl Checksum for tcp_h"],["impl Checksum for arp_h"],["impl Checksum for ddm_element_t"],["impl Checksum for geneve_h"],["impl Checksum for sidecar_h"],["impl Checksum for ipv4_h"],["impl Checksum for udp_h"],["impl Checksum for vlan_h"],["impl Checksum for ipv6_h"],["impl Checksum for icmp_h"],["impl Checksum for ddm_h"],["impl Checksum for ethernet_h"]], +"vlan_switch":[["impl Checksum for sidecar_h"],["impl Checksum for icmp_h"],["impl Checksum for ethernet_h"],["impl Checksum for udp_h"],["impl Checksum for vlan_h"],["impl Checksum for ipv4_h"],["impl Checksum for tcp_h"],["impl Checksum for ipv6_h"],["impl Checksum for geneve_h"],["impl Checksum for ddm_h"],["impl Checksum for ddm_element_t"],["impl Checksum for arp_h"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/p4rs/trait.Header.js b/trait.impl/p4rs/trait.Header.js new file mode 100644 index 00000000..5a587a03 --- /dev/null +++ b/trait.impl/p4rs/trait.Header.js @@ -0,0 +1,6 @@ +(function() {var implementors = { +"hello_world":[["impl Header for ethernet_h"]], +"p4_macro_test":[["impl Header for ethernet_t"]], +"sidecar_lite":[["impl Header for udp_h"],["impl Header for ipv4_h"],["impl Header for arp_h"],["impl Header for geneve_h"],["impl Header for ddm_h"],["impl Header for icmp_h"],["impl Header for sidecar_h"],["impl Header for ipv6_h"],["impl Header for vlan_h"],["impl Header for ddm_element_t"],["impl Header for tcp_h"],["impl Header for ethernet_h"]], +"vlan_switch":[["impl Header for vlan_h"],["impl Header for geneve_h"],["impl Header for sidecar_h"],["impl Header for arp_h"],["impl Header for ipv4_h"],["impl Header for ddm_h"],["impl Header for ipv6_h"],["impl Header for icmp_h"],["impl Header for udp_h"],["impl Header for ddm_element_t"],["impl Header for tcp_h"],["impl Header for ethernet_h"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/p4rs/trait.Pipeline.js b/trait.impl/p4rs/trait.Pipeline.js new file mode 100644 index 00000000..b517347a --- /dev/null +++ b/trait.impl/p4rs/trait.Pipeline.js @@ -0,0 +1,5 @@ +(function() {var implementors = { +"hello_world":[["impl Pipeline for main_pipeline"]], +"sidecar_lite":[["impl Pipeline for main_pipeline"]], +"vlan_switch":[["impl Pipeline for main_pipeline"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/serde/de/trait.Deserialize.js b/trait.impl/serde/de/trait.Deserialize.js new file mode 100644 index 00000000..c684ef6c --- /dev/null +++ b/trait.impl/serde/de/trait.Deserialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4rs":[["impl<'de> Deserialize<'de> for BigUintKey"],["impl<'de> Deserialize<'de> for Ternary"],["impl<'de> Deserialize<'de> for TableEntry"],["impl<'de> Deserialize<'de> for Prefix"],["impl<'de> Deserialize<'de> for Key"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/trait.impl/serde/ser/trait.Serialize.js b/trait.impl/serde/ser/trait.Serialize.js new file mode 100644 index 00000000..4961a162 --- /dev/null +++ b/trait.impl/serde/ser/trait.Serialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"p4rs":[["impl Serialize for Key"],["impl Serialize for Ternary"],["impl Serialize for BigUintKey"],["impl Serialize for TableEntry"],["impl Serialize for Prefix"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/vlan_switch/all.html b/vlan_switch/all.html new file mode 100644 index 00000000..11289826 --- /dev/null +++ b/vlan_switch/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +
\ No newline at end of file diff --git a/vlan_switch/fn._vlan_switch_pipeline_create.html b/vlan_switch/fn._vlan_switch_pipeline_create.html new file mode 100644 index 00000000..2e1c37f9 --- /dev/null +++ b/vlan_switch/fn._vlan_switch_pipeline_create.html @@ -0,0 +1,5 @@ +_vlan_switch_pipeline_create in vlan_switch - Rust +
#[no_mangle]
+pub extern "C" fn _vlan_switch_pipeline_create(
+    radix: u16
+) -> *mut dyn Pipeline
\ No newline at end of file diff --git a/vlan_switch/fn.egress_apply.html b/vlan_switch/fn.egress_apply.html new file mode 100644 index 00000000..58db79bc --- /dev/null +++ b/vlan_switch/fn.egress_apply.html @@ -0,0 +1,6 @@ +egress_apply in vlan_switch - Rust +

Function vlan_switch::egress_apply

source ·
pub fn egress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t
+)
\ No newline at end of file diff --git a/vlan_switch/fn.forward_action_drop.html b/vlan_switch/fn.forward_action_drop.html new file mode 100644 index 00000000..0a8f9118 --- /dev/null +++ b/vlan_switch/fn.forward_action_drop.html @@ -0,0 +1,2 @@ +forward_action_drop in vlan_switch - Rust +
pub fn forward_action_drop(hdr: &mut headers_t, egress: &mut egress_metadata_t)
\ No newline at end of file diff --git a/vlan_switch/fn.forward_action_forward.html b/vlan_switch/fn.forward_action_forward.html new file mode 100644 index 00000000..f612d5cd --- /dev/null +++ b/vlan_switch/fn.forward_action_forward.html @@ -0,0 +1,6 @@ +forward_action_forward in vlan_switch - Rust +
pub fn forward_action_forward(
+    hdr: &mut headers_t,
+    egress: &mut egress_metadata_t,
+    port: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/vlan_switch/fn.forward_apply.html b/vlan_switch/fn.forward_apply.html new file mode 100644 index 00000000..ec52e018 --- /dev/null +++ b/vlan_switch/fn.forward_apply.html @@ -0,0 +1,6 @@ +forward_apply in vlan_switch - Rust +

Function vlan_switch::forward_apply

source ·
pub fn forward_apply(
+    hdr: &mut headers_t,
+    egress: &mut egress_metadata_t,
+    fib: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/vlan_switch/fn.ingress_apply.html b/vlan_switch/fn.ingress_apply.html new file mode 100644 index 00000000..57b5cec2 --- /dev/null +++ b/vlan_switch/fn.ingress_apply.html @@ -0,0 +1,8 @@ +ingress_apply in vlan_switch - Rust +

Function vlan_switch::ingress_apply

source ·
pub fn ingress_apply(
+    hdr: &mut headers_t,
+    ingress: &mut ingress_metadata_t,
+    egress: &mut egress_metadata_t,
+    vlan_port_vlan: &Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>,
+    fwd_fib: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
+)
\ No newline at end of file diff --git a/vlan_switch/fn.ingress_fwd_fib.html b/vlan_switch/fn.ingress_fwd_fib.html new file mode 100644 index 00000000..452714c7 --- /dev/null +++ b/vlan_switch/fn.ingress_fwd_fib.html @@ -0,0 +1,3 @@ +ingress_fwd_fib in vlan_switch - Rust +
pub fn ingress_fwd_fib(
+) -> Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>
\ No newline at end of file diff --git a/vlan_switch/fn.ingress_vlan_port_vlan.html b/vlan_switch/fn.ingress_vlan_port_vlan.html new file mode 100644 index 00000000..5771d89b --- /dev/null +++ b/vlan_switch/fn.ingress_vlan_port_vlan.html @@ -0,0 +1,3 @@ +ingress_vlan_port_vlan in vlan_switch - Rust +
pub fn ingress_vlan_port_vlan(
+) -> Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>
\ No newline at end of file diff --git a/vlan_switch/fn.init_tables.html b/vlan_switch/fn.init_tables.html new file mode 100644 index 00000000..acc1478a --- /dev/null +++ b/vlan_switch/fn.init_tables.html @@ -0,0 +1,6 @@ +init_tables in vlan_switch - Rust +

Function vlan_switch::init_tables

source ·
pub(crate) fn init_tables(
+    pipeline: &mut main_pipeline,
+    m1: [u8; 6],
+    m2: [u8; 6]
+)
\ No newline at end of file diff --git a/vlan_switch/fn.main.html b/vlan_switch/fn.main.html new file mode 100644 index 00000000..0b6be20e --- /dev/null +++ b/vlan_switch/fn.main.html @@ -0,0 +1,2 @@ +main in vlan_switch - Rust +

Function vlan_switch::main

source ·
pub(crate) fn main() -> Result<(), Error>
\ No newline at end of file diff --git a/vlan_switch/fn.parse_start.html b/vlan_switch/fn.parse_start.html new file mode 100644 index 00000000..0cfda1f2 --- /dev/null +++ b/vlan_switch/fn.parse_start.html @@ -0,0 +1,6 @@ +parse_start in vlan_switch - Rust +

Function vlan_switch::parse_start

source ·
pub fn parse_start(
+    pkt: &mut packet_in<'_>,
+    h: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/vlan_switch/fn.parse_vlan.html b/vlan_switch/fn.parse_vlan.html new file mode 100644 index 00000000..06129ace --- /dev/null +++ b/vlan_switch/fn.parse_vlan.html @@ -0,0 +1,6 @@ +parse_vlan in vlan_switch - Rust +

Function vlan_switch::parse_vlan

source ·
pub fn parse_vlan(
+    pkt: &mut packet_in<'_>,
+    h: &mut headers_t,
+    ingress: &mut ingress_metadata_t
+) -> bool
\ No newline at end of file diff --git a/vlan_switch/fn.run_test.html b/vlan_switch/fn.run_test.html new file mode 100644 index 00000000..a8e484c2 --- /dev/null +++ b/vlan_switch/fn.run_test.html @@ -0,0 +1,6 @@ +run_test in vlan_switch - Rust +

Function vlan_switch::run_test

source ·
pub(crate) fn run_test(
+    pipeline: main_pipeline,
+    m2: [u8; 6],
+    m3: [u8; 6]
+) -> Result<(), Error>
\ No newline at end of file diff --git a/vlan_switch/fn.vlan_action_filter.html b/vlan_switch/fn.vlan_action_filter.html new file mode 100644 index 00000000..afdbd927 --- /dev/null +++ b/vlan_switch/fn.vlan_action_filter.html @@ -0,0 +1,7 @@ +vlan_action_filter in vlan_switch - Rust +
pub fn vlan_action_filter(
+    port: &BitVec<u8, Msb0>,
+    vid: &BitVec<u8, Msb0>,
+    match_: &mut bool,
+    port_vid: BitVec<u8, Msb0>
+)
\ No newline at end of file diff --git a/vlan_switch/fn.vlan_action_no_vid_for_port.html b/vlan_switch/fn.vlan_action_no_vid_for_port.html new file mode 100644 index 00000000..451d815b --- /dev/null +++ b/vlan_switch/fn.vlan_action_no_vid_for_port.html @@ -0,0 +1,6 @@ +vlan_action_no_vid_for_port in vlan_switch - Rust +
pub fn vlan_action_no_vid_for_port(
+    port: &BitVec<u8, Msb0>,
+    vid: &BitVec<u8, Msb0>,
+    match_: &mut bool
+)
\ No newline at end of file diff --git a/vlan_switch/fn.vlan_apply.html b/vlan_switch/fn.vlan_apply.html new file mode 100644 index 00000000..03b334d9 --- /dev/null +++ b/vlan_switch/fn.vlan_apply.html @@ -0,0 +1,7 @@ +vlan_apply in vlan_switch - Rust +

Function vlan_switch::vlan_apply

source ·
pub fn vlan_apply(
+    port: &BitVec<u8, Msb0>,
+    vid: &BitVec<u8, Msb0>,
+    match_: &mut bool,
+    port_vlan: &Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>
+)
\ No newline at end of file diff --git a/vlan_switch/index.html b/vlan_switch/index.html new file mode 100644 index 00000000..689d4765 --- /dev/null +++ b/vlan_switch/index.html @@ -0,0 +1,3 @@ +vlan_switch - Rust +
\ No newline at end of file diff --git a/vlan_switch/sidebar-items.js b/vlan_switch/sidebar-items.js new file mode 100644 index 00000000..eb4eb562 --- /dev/null +++ b/vlan_switch/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["_vlan_switch_pipeline_create","egress_apply","forward_action_drop","forward_action_forward","forward_apply","ingress_apply","ingress_fwd_fib","ingress_vlan_port_vlan","init_tables","main","parse_start","parse_vlan","run_test","vlan_action_filter","vlan_action_no_vid_for_port","vlan_apply"],"mod":["softnpu_provider"],"struct":["arp_h","ddm_element_t","ddm_h","egress_metadata_t","ethernet_h","geneve_h","headers_t","icmp_h","ingress_metadata_t","ipv4_h","ipv6_h","main_pipeline","sidecar_h","tcp_h","udp_h","vlan_h"]}; \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/index.html b/vlan_switch/softnpu_provider/index.html new file mode 100644 index 00000000..ebae2ce3 --- /dev/null +++ b/vlan_switch/softnpu_provider/index.html @@ -0,0 +1,2 @@ +vlan_switch::softnpu_provider - Rust +
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.action!.html b/vlan_switch/softnpu_provider/macro.action!.html new file mode 100644 index 00000000..d4ab696b --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.action!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.action.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.action.html b/vlan_switch/softnpu_provider/macro.action.html new file mode 100644 index 00000000..e6c844d8 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.action.html @@ -0,0 +1,5 @@ +action in vlan_switch::softnpu_provider - Rust +
macro_rules! action {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.control_apply!.html b/vlan_switch/softnpu_provider/macro.control_apply!.html new file mode 100644 index 00000000..30ff9a1c --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.control_apply!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_apply.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.control_apply.html b/vlan_switch/softnpu_provider/macro.control_apply.html new file mode 100644 index 00000000..716aa4e5 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.control_apply.html @@ -0,0 +1,5 @@ +control_apply in vlan_switch::softnpu_provider - Rust +
macro_rules! control_apply {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.control_table_hit!.html b/vlan_switch/softnpu_provider/macro.control_table_hit!.html new file mode 100644 index 00000000..b2c3113d --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.control_table_hit!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_table_hit.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.control_table_hit.html b/vlan_switch/softnpu_provider/macro.control_table_hit.html new file mode 100644 index 00000000..4ffe38d6 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.control_table_hit.html @@ -0,0 +1,5 @@ +control_table_hit in vlan_switch::softnpu_provider - Rust +
macro_rules! control_table_hit {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.control_table_miss!.html b/vlan_switch/softnpu_provider/macro.control_table_miss!.html new file mode 100644 index 00000000..6c9107c1 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.control_table_miss!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.control_table_miss.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.control_table_miss.html b/vlan_switch/softnpu_provider/macro.control_table_miss.html new file mode 100644 index 00000000..51e52dfd --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.control_table_miss.html @@ -0,0 +1,5 @@ +control_table_miss in vlan_switch::softnpu_provider - Rust +
macro_rules! control_table_miss {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_accepted!.html b/vlan_switch/softnpu_provider/macro.egress_accepted!.html new file mode 100644 index 00000000..bd4b37c4 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_accepted.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_accepted.html b/vlan_switch/softnpu_provider/macro.egress_accepted.html new file mode 100644 index 00000000..bfeda592 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_accepted.html @@ -0,0 +1,5 @@ +egress_accepted in vlan_switch::softnpu_provider - Rust +
macro_rules! egress_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_dropped!.html b/vlan_switch/softnpu_provider/macro.egress_dropped!.html new file mode 100644 index 00000000..3045dc36 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_dropped.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_dropped.html b/vlan_switch/softnpu_provider/macro.egress_dropped.html new file mode 100644 index 00000000..5846d5eb --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_dropped.html @@ -0,0 +1,5 @@ +egress_dropped in vlan_switch::softnpu_provider - Rust +
macro_rules! egress_dropped {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_table_hit!.html b/vlan_switch/softnpu_provider/macro.egress_table_hit!.html new file mode 100644 index 00000000..04b83478 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_table_hit!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_table_hit.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_table_hit.html b/vlan_switch/softnpu_provider/macro.egress_table_hit.html new file mode 100644 index 00000000..4471022a --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_table_hit.html @@ -0,0 +1,5 @@ +egress_table_hit in vlan_switch::softnpu_provider - Rust +
macro_rules! egress_table_hit {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_table_miss!.html b/vlan_switch/softnpu_provider/macro.egress_table_miss!.html new file mode 100644 index 00000000..686d6e77 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_table_miss!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.egress_table_miss.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.egress_table_miss.html b/vlan_switch/softnpu_provider/macro.egress_table_miss.html new file mode 100644 index 00000000..3755735d --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.egress_table_miss.html @@ -0,0 +1,5 @@ +egress_table_miss in vlan_switch::softnpu_provider - Rust +
macro_rules! egress_table_miss {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.ingress_accepted!.html b/vlan_switch/softnpu_provider/macro.ingress_accepted!.html new file mode 100644 index 00000000..0640a788 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.ingress_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.ingress_accepted.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.ingress_accepted.html b/vlan_switch/softnpu_provider/macro.ingress_accepted.html new file mode 100644 index 00000000..44c9b297 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.ingress_accepted.html @@ -0,0 +1,5 @@ +ingress_accepted in vlan_switch::softnpu_provider - Rust +
macro_rules! ingress_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.ingress_dropped!.html b/vlan_switch/softnpu_provider/macro.ingress_dropped!.html new file mode 100644 index 00000000..e0505f61 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.ingress_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.ingress_dropped.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.ingress_dropped.html b/vlan_switch/softnpu_provider/macro.ingress_dropped.html new file mode 100644 index 00000000..5ecf2b9e --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.ingress_dropped.html @@ -0,0 +1,5 @@ +ingress_dropped in vlan_switch::softnpu_provider - Rust +
macro_rules! ingress_dropped {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.parser_accepted!.html b/vlan_switch/softnpu_provider/macro.parser_accepted!.html new file mode 100644 index 00000000..cfa1b466 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.parser_accepted!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_accepted.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.parser_accepted.html b/vlan_switch/softnpu_provider/macro.parser_accepted.html new file mode 100644 index 00000000..205d49d7 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.parser_accepted.html @@ -0,0 +1,5 @@ +parser_accepted in vlan_switch::softnpu_provider - Rust +
macro_rules! parser_accepted {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.parser_dropped!.html b/vlan_switch/softnpu_provider/macro.parser_dropped!.html new file mode 100644 index 00000000..de167747 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.parser_dropped!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_dropped.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.parser_dropped.html b/vlan_switch/softnpu_provider/macro.parser_dropped.html new file mode 100644 index 00000000..aead59b3 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.parser_dropped.html @@ -0,0 +1,6 @@ +parser_dropped in vlan_switch::softnpu_provider - Rust +
macro_rules! parser_dropped {
+    () => { ... };
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.parser_transition!.html b/vlan_switch/softnpu_provider/macro.parser_transition!.html new file mode 100644 index 00000000..605298f0 --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.parser_transition!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.parser_transition.html...

+ + + \ No newline at end of file diff --git a/vlan_switch/softnpu_provider/macro.parser_transition.html b/vlan_switch/softnpu_provider/macro.parser_transition.html new file mode 100644 index 00000000..3f331eeb --- /dev/null +++ b/vlan_switch/softnpu_provider/macro.parser_transition.html @@ -0,0 +1,5 @@ +parser_transition in vlan_switch::softnpu_provider - Rust +
macro_rules! parser_transition {
+    ($tree:tt) => { ... };
+    ($args_lambda:expr) => { ... };
+}
\ No newline at end of file diff --git a/vlan_switch/softnpu_provider/sidebar-items.js b/vlan_switch/softnpu_provider/sidebar-items.js new file mode 100644 index 00000000..3e3f1355 --- /dev/null +++ b/vlan_switch/softnpu_provider/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"macro":["action","control_apply","control_table_hit","control_table_miss","egress_accepted","egress_dropped","egress_table_hit","egress_table_miss","ingress_accepted","ingress_dropped","parser_accepted","parser_dropped","parser_transition"]}; \ No newline at end of file diff --git a/vlan_switch/struct.arp_h.html b/vlan_switch/struct.arp_h.html new file mode 100644 index 00000000..a6f1a806 --- /dev/null +++ b/vlan_switch/struct.arp_h.html @@ -0,0 +1,104 @@ +arp_h in vlan_switch - Rust +

Struct vlan_switch::arp_h

source ·
pub struct arp_h {
+    pub valid: bool,
+    pub hw_type: BitVec<u8, Msb0>,
+    pub proto_type: BitVec<u8, Msb0>,
+    pub hw_addr_len: BitVec<u8, Msb0>,
+    pub proto_addr_len: BitVec<u8, Msb0>,
+    pub opcode: BitVec<u8, Msb0>,
+    pub sender_mac: BitVec<u8, Msb0>,
+    pub sender_ip: BitVec<u8, Msb0>,
+    pub target_mac: BitVec<u8, Msb0>,
+    pub target_ip: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§hw_type: BitVec<u8, Msb0>§proto_type: BitVec<u8, Msb0>§hw_addr_len: BitVec<u8, Msb0>§proto_addr_len: BitVec<u8, Msb0>§opcode: BitVec<u8, Msb0>§sender_mac: BitVec<u8, Msb0>§sender_ip: BitVec<u8, Msb0>§target_mac: BitVec<u8, Msb0>§target_ip: BitVec<u8, Msb0>

Implementations§

source§

impl arp_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for arp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for arp_h

source§

fn clone(&self) -> arp_h

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 Debug for arp_h

source§

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

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

impl Default for arp_h

source§

fn default() -> arp_h

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

impl Header for arp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for arp_h

§

impl Send for arp_h

§

impl Sync for arp_h

§

impl Unpin for arp_h

§

impl UnwindSafe for arp_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.ddm_element_t.html b/vlan_switch/struct.ddm_element_t.html new file mode 100644 index 00000000..ba1fb21f --- /dev/null +++ b/vlan_switch/struct.ddm_element_t.html @@ -0,0 +1,97 @@ +ddm_element_t in vlan_switch - Rust +
pub struct ddm_element_t {
+    pub valid: bool,
+    pub id: BitVec<u8, Msb0>,
+    pub timestamp: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§id: BitVec<u8, Msb0>§timestamp: BitVec<u8, Msb0>

Implementations§

source§

impl ddm_element_t

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ddm_element_t

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ddm_element_t

source§

fn clone(&self) -> ddm_element_t

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 Debug for ddm_element_t

source§

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

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

impl Default for ddm_element_t

source§

fn default() -> ddm_element_t

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

impl Header for ddm_element_t

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.ddm_h.html b/vlan_switch/struct.ddm_h.html new file mode 100644 index 00000000..a9d9dbe7 --- /dev/null +++ b/vlan_switch/struct.ddm_h.html @@ -0,0 +1,100 @@ +ddm_h in vlan_switch - Rust +

Struct vlan_switch::ddm_h

source ·
pub struct ddm_h {
+    pub valid: bool,
+    pub next_header: BitVec<u8, Msb0>,
+    pub header_length: BitVec<u8, Msb0>,
+    pub version: BitVec<u8, Msb0>,
+    pub ack: BitVec<u8, Msb0>,
+    pub reserved: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§next_header: BitVec<u8, Msb0>§header_length: BitVec<u8, Msb0>§version: BitVec<u8, Msb0>§ack: BitVec<u8, Msb0>§reserved: BitVec<u8, Msb0>

Implementations§

source§

impl ddm_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ddm_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ddm_h

source§

fn clone(&self) -> ddm_h

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 Debug for ddm_h

source§

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

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

impl Default for ddm_h

source§

fn default() -> ddm_h

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

impl Header for ddm_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for ddm_h

§

impl Send for ddm_h

§

impl Sync for ddm_h

§

impl Unpin for ddm_h

§

impl UnwindSafe for ddm_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.egress_metadata_t.html b/vlan_switch/struct.egress_metadata_t.html new file mode 100644 index 00000000..97aff60a --- /dev/null +++ b/vlan_switch/struct.egress_metadata_t.html @@ -0,0 +1,99 @@ +egress_metadata_t in vlan_switch - Rust +
pub struct egress_metadata_t {
+    pub port: BitVec<u8, Msb0>,
+    pub nexthop_v6: BitVec<u8, Msb0>,
+    pub nexthop_v4: BitVec<u8, Msb0>,
+    pub drop: bool,
+    pub broadcast: bool,
+}

Fields§

§port: BitVec<u8, Msb0>§nexthop_v6: BitVec<u8, Msb0>§nexthop_v4: BitVec<u8, Msb0>§drop: bool§broadcast: bool

Implementations§

source§

impl egress_metadata_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for egress_metadata_t

source§

fn clone(&self) -> egress_metadata_t

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 Debug for egress_metadata_t

source§

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

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

impl Default for egress_metadata_t

source§

fn default() -> egress_metadata_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.ethernet_h.html b/vlan_switch/struct.ethernet_h.html new file mode 100644 index 00000000..91c38df0 --- /dev/null +++ b/vlan_switch/struct.ethernet_h.html @@ -0,0 +1,98 @@ +ethernet_h in vlan_switch - Rust +

Struct vlan_switch::ethernet_h

source ·
pub struct ethernet_h {
+    pub valid: bool,
+    pub dst: BitVec<u8, Msb0>,
+    pub src: BitVec<u8, Msb0>,
+    pub ether_type: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§dst: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§ether_type: BitVec<u8, Msb0>

Implementations§

source§

impl ethernet_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ethernet_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ethernet_h

source§

fn clone(&self) -> ethernet_h

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 Debug for ethernet_h

source§

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

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

impl Default for ethernet_h

source§

fn default() -> ethernet_h

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

impl Header for ethernet_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.geneve_h.html b/vlan_switch/struct.geneve_h.html new file mode 100644 index 00000000..7b81cc53 --- /dev/null +++ b/vlan_switch/struct.geneve_h.html @@ -0,0 +1,103 @@ +geneve_h in vlan_switch - Rust +

Struct vlan_switch::geneve_h

source ·
pub struct geneve_h {
+    pub valid: bool,
+    pub version: BitVec<u8, Msb0>,
+    pub opt_len: BitVec<u8, Msb0>,
+    pub ctrl: BitVec<u8, Msb0>,
+    pub crit: BitVec<u8, Msb0>,
+    pub reserved: BitVec<u8, Msb0>,
+    pub protocol: BitVec<u8, Msb0>,
+    pub vni: BitVec<u8, Msb0>,
+    pub reserved2: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§version: BitVec<u8, Msb0>§opt_len: BitVec<u8, Msb0>§ctrl: BitVec<u8, Msb0>§crit: BitVec<u8, Msb0>§reserved: BitVec<u8, Msb0>§protocol: BitVec<u8, Msb0>§vni: BitVec<u8, Msb0>§reserved2: BitVec<u8, Msb0>

Implementations§

source§

impl geneve_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for geneve_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for geneve_h

source§

fn clone(&self) -> geneve_h

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 Debug for geneve_h

source§

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

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

impl Default for geneve_h

source§

fn default() -> geneve_h

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

impl Header for geneve_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.headers_t.html b/vlan_switch/struct.headers_t.html new file mode 100644 index 00000000..62747dfc --- /dev/null +++ b/vlan_switch/struct.headers_t.html @@ -0,0 +1,96 @@ +headers_t in vlan_switch - Rust +

Struct vlan_switch::headers_t

source ·
pub struct headers_t {
+    pub eth: ethernet_h,
+    pub vlan: vlan_h,
+}

Fields§

§eth: ethernet_h§vlan: vlan_h

Implementations§

source§

impl headers_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for headers_t

source§

fn clone(&self) -> headers_t

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 Debug for headers_t

source§

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

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

impl Default for headers_t

source§

fn default() -> headers_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.icmp_h.html b/vlan_switch/struct.icmp_h.html new file mode 100644 index 00000000..99014e12 --- /dev/null +++ b/vlan_switch/struct.icmp_h.html @@ -0,0 +1,99 @@ +icmp_h in vlan_switch - Rust +

Struct vlan_switch::icmp_h

source ·
pub struct icmp_h {
+    pub valid: bool,
+    pub typ: BitVec<u8, Msb0>,
+    pub code: BitVec<u8, Msb0>,
+    pub hdr_checksum: BitVec<u8, Msb0>,
+    pub data: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§typ: BitVec<u8, Msb0>§code: BitVec<u8, Msb0>§hdr_checksum: BitVec<u8, Msb0>§data: BitVec<u8, Msb0>

Implementations§

source§

impl icmp_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for icmp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for icmp_h

source§

fn clone(&self) -> icmp_h

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 Debug for icmp_h

source§

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

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

impl Default for icmp_h

source§

fn default() -> icmp_h

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

impl Header for icmp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.ingress_metadata_t.html b/vlan_switch/struct.ingress_metadata_t.html new file mode 100644 index 00000000..1ecb172a --- /dev/null +++ b/vlan_switch/struct.ingress_metadata_t.html @@ -0,0 +1,98 @@ +ingress_metadata_t in vlan_switch - Rust +
pub struct ingress_metadata_t {
+    pub port: BitVec<u8, Msb0>,
+    pub nat: bool,
+    pub nat_id: BitVec<u8, Msb0>,
+    pub drop: bool,
+}

Fields§

§port: BitVec<u8, Msb0>§nat: bool§nat_id: BitVec<u8, Msb0>§drop: bool

Implementations§

source§

impl ingress_metadata_t

source

pub(crate) fn valid_header_size(&self) -> usize

source

pub(crate) fn to_bitvec(&self) -> BitVec<u8, Msb0>

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Clone for ingress_metadata_t

source§

fn clone(&self) -> ingress_metadata_t

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 Debug for ingress_metadata_t

source§

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

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

impl Default for ingress_metadata_t

source§

fn default() -> ingress_metadata_t

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

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.ipv4_h.html b/vlan_switch/struct.ipv4_h.html new file mode 100644 index 00000000..9cd129f1 --- /dev/null +++ b/vlan_switch/struct.ipv4_h.html @@ -0,0 +1,107 @@ +ipv4_h in vlan_switch - Rust +

Struct vlan_switch::ipv4_h

source ·
pub struct ipv4_h {
Show 13 fields + pub valid: bool, + pub version: BitVec<u8, Msb0>, + pub ihl: BitVec<u8, Msb0>, + pub diffserv: BitVec<u8, Msb0>, + pub total_len: BitVec<u8, Msb0>, + pub identification: BitVec<u8, Msb0>, + pub flags: BitVec<u8, Msb0>, + pub frag_offset: BitVec<u8, Msb0>, + pub ttl: BitVec<u8, Msb0>, + pub protocol: BitVec<u8, Msb0>, + pub hdr_checksum: BitVec<u8, Msb0>, + pub src: BitVec<u8, Msb0>, + pub dst: BitVec<u8, Msb0>, +
}

Fields§

§valid: bool§version: BitVec<u8, Msb0>§ihl: BitVec<u8, Msb0>§diffserv: BitVec<u8, Msb0>§total_len: BitVec<u8, Msb0>§identification: BitVec<u8, Msb0>§flags: BitVec<u8, Msb0>§frag_offset: BitVec<u8, Msb0>§ttl: BitVec<u8, Msb0>§protocol: BitVec<u8, Msb0>§hdr_checksum: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§dst: BitVec<u8, Msb0>

Implementations§

source§

impl ipv4_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ipv4_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ipv4_h

source§

fn clone(&self) -> ipv4_h

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 Debug for ipv4_h

source§

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

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

impl Default for ipv4_h

source§

fn default() -> ipv4_h

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

impl Header for ipv4_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.ipv6_h.html b/vlan_switch/struct.ipv6_h.html new file mode 100644 index 00000000..67ebe942 --- /dev/null +++ b/vlan_switch/struct.ipv6_h.html @@ -0,0 +1,103 @@ +ipv6_h in vlan_switch - Rust +

Struct vlan_switch::ipv6_h

source ·
pub struct ipv6_h {
+    pub valid: bool,
+    pub version: BitVec<u8, Msb0>,
+    pub traffic_class: BitVec<u8, Msb0>,
+    pub flow_label: BitVec<u8, Msb0>,
+    pub payload_len: BitVec<u8, Msb0>,
+    pub next_hdr: BitVec<u8, Msb0>,
+    pub hop_limit: BitVec<u8, Msb0>,
+    pub src: BitVec<u8, Msb0>,
+    pub dst: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§version: BitVec<u8, Msb0>§traffic_class: BitVec<u8, Msb0>§flow_label: BitVec<u8, Msb0>§payload_len: BitVec<u8, Msb0>§next_hdr: BitVec<u8, Msb0>§hop_limit: BitVec<u8, Msb0>§src: BitVec<u8, Msb0>§dst: BitVec<u8, Msb0>

Implementations§

source§

impl ipv6_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for ipv6_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for ipv6_h

source§

fn clone(&self) -> ipv6_h

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 Debug for ipv6_h

source§

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

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

impl Default for ipv6_h

source§

fn default() -> ipv6_h

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

impl Header for ipv6_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.main_pipeline.html b/vlan_switch/struct.main_pipeline.html new file mode 100644 index 00000000..d9faf232 --- /dev/null +++ b/vlan_switch/struct.main_pipeline.html @@ -0,0 +1,128 @@ +main_pipeline in vlan_switch - Rust +
pub struct main_pipeline {
+    pub ingress_vlan_port_vlan: Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>,
+    pub ingress_fwd_fib: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>,
+    pub parse: fn(pkt: &mut packet_in<'_>, h: &mut headers_t, ingress: &mut ingress_metadata_t) -> bool,
+    pub ingress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t, vlan_port_vlan: &Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>, fwd_fib: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>),
+    pub egress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t),
+    pub(crate) radix: u16,
+}

Fields§

§ingress_vlan_port_vlan: Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>§ingress_fwd_fib: Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>§parse: fn(pkt: &mut packet_in<'_>, h: &mut headers_t, ingress: &mut ingress_metadata_t) -> bool§ingress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t, vlan_port_vlan: &Table<1usize, Arc<dyn Fn(&BitVec<u8, Msb0>, &BitVec<u8, Msb0>, &mut bool)>>, fwd_fib: &Table<1usize, Arc<dyn Fn(&mut headers_t, &mut egress_metadata_t)>>)§egress: fn(hdr: &mut headers_t, ingress: &mut ingress_metadata_t, egress: &mut egress_metadata_t)§radix: u16

Implementations§

source§

impl main_pipeline

source

pub fn new(radix: u16) -> Self

source

pub(crate) fn process_packet_headers<'a>( + &mut self, + port: u16, + pkt: &mut packet_in<'a> +) -> Vec<(headers_t, u16)>

source

pub fn add_ingress_vlan_port_vlan_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_vlan_port_vlan_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_vlan_port_vlan_entries(&self) -> Vec<TableEntry>

source

pub fn add_ingress_fwd_fib_entry<'a>( + &mut self, + action_id: &str, + keyset_data: &'a [u8], + parameter_data: &'a [u8], + priority: u32 +)

source

pub fn remove_ingress_fwd_fib_entry<'a>(&mut self, keyset_data: &'a [u8])

source

pub fn get_ingress_fwd_fib_entries(&self) -> Vec<TableEntry>

Trait Implementations§

source§

impl Pipeline for main_pipeline

source§

fn process_packet<'a>( + &mut self, + port: u16, + pkt: &mut packet_in<'a> +) -> Vec<(packet_out<'a>, u16)>

Process an input packet and produce a set of output packets. Normally +there will be a single output packet. However, if the pipeline sets +egress_metadata_t.broadcast there may be multiple output packets.
source§

fn add_table_entry( + &mut self, + table_id: &str, + action_id: &str, + keyset_data: &[u8], + parameter_data: &[u8], + priority: u32 +)

Add an entry to a table identified by table_id.
source§

fn remove_table_entry(&mut self, table_id: &str, keyset_data: &[u8])

Remove an entry from a table identified by table_id.
source§

fn get_table_entries(&self, table_id: &str) -> Option<Vec<TableEntry>>

Get all the entries in a table.
source§

fn get_table_ids(&self) -> Vec<&str>

Get a list of table ids
source§

impl Send for main_pipeline

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.sidecar_h.html b/vlan_switch/struct.sidecar_h.html new file mode 100644 index 00000000..708bd8eb --- /dev/null +++ b/vlan_switch/struct.sidecar_h.html @@ -0,0 +1,100 @@ +sidecar_h in vlan_switch - Rust +

Struct vlan_switch::sidecar_h

source ·
pub struct sidecar_h {
+    pub valid: bool,
+    pub sc_code: BitVec<u8, Msb0>,
+    pub sc_ingress: BitVec<u8, Msb0>,
+    pub sc_egress: BitVec<u8, Msb0>,
+    pub sc_ether_type: BitVec<u8, Msb0>,
+    pub sc_payload: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§sc_code: BitVec<u8, Msb0>§sc_ingress: BitVec<u8, Msb0>§sc_egress: BitVec<u8, Msb0>§sc_ether_type: BitVec<u8, Msb0>§sc_payload: BitVec<u8, Msb0>

Implementations§

source§

impl sidecar_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for sidecar_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for sidecar_h

source§

fn clone(&self) -> sidecar_h

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 Debug for sidecar_h

source§

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

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

impl Default for sidecar_h

source§

fn default() -> sidecar_h

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

impl Header for sidecar_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.tcp_h.html b/vlan_switch/struct.tcp_h.html new file mode 100644 index 00000000..12d3e579 --- /dev/null +++ b/vlan_switch/struct.tcp_h.html @@ -0,0 +1,105 @@ +tcp_h in vlan_switch - Rust +

Struct vlan_switch::tcp_h

source ·
pub struct tcp_h {
+    pub valid: bool,
+    pub src_port: BitVec<u8, Msb0>,
+    pub dst_port: BitVec<u8, Msb0>,
+    pub seq_no: BitVec<u8, Msb0>,
+    pub ack_no: BitVec<u8, Msb0>,
+    pub data_offset: BitVec<u8, Msb0>,
+    pub res: BitVec<u8, Msb0>,
+    pub flags: BitVec<u8, Msb0>,
+    pub window: BitVec<u8, Msb0>,
+    pub checksum: BitVec<u8, Msb0>,
+    pub urgent_ptr: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§src_port: BitVec<u8, Msb0>§dst_port: BitVec<u8, Msb0>§seq_no: BitVec<u8, Msb0>§ack_no: BitVec<u8, Msb0>§data_offset: BitVec<u8, Msb0>§res: BitVec<u8, Msb0>§flags: BitVec<u8, Msb0>§window: BitVec<u8, Msb0>§checksum: BitVec<u8, Msb0>§urgent_ptr: BitVec<u8, Msb0>

Implementations§

source§

impl tcp_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for tcp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for tcp_h

source§

fn clone(&self) -> tcp_h

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 Debug for tcp_h

source§

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

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

impl Default for tcp_h

source§

fn default() -> tcp_h

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

impl Header for tcp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for tcp_h

§

impl Send for tcp_h

§

impl Sync for tcp_h

§

impl Unpin for tcp_h

§

impl UnwindSafe for tcp_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.udp_h.html b/vlan_switch/struct.udp_h.html new file mode 100644 index 00000000..581d2e84 --- /dev/null +++ b/vlan_switch/struct.udp_h.html @@ -0,0 +1,99 @@ +udp_h in vlan_switch - Rust +

Struct vlan_switch::udp_h

source ·
pub struct udp_h {
+    pub valid: bool,
+    pub src_port: BitVec<u8, Msb0>,
+    pub dst_port: BitVec<u8, Msb0>,
+    pub len: BitVec<u8, Msb0>,
+    pub checksum: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§src_port: BitVec<u8, Msb0>§dst_port: BitVec<u8, Msb0>§len: BitVec<u8, Msb0>§checksum: BitVec<u8, Msb0>

Implementations§

source§

impl udp_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for udp_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for udp_h

source§

fn clone(&self) -> udp_h

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 Debug for udp_h

source§

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

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

impl Default for udp_h

source§

fn default() -> udp_h

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

impl Header for udp_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

§

impl RefUnwindSafe for udp_h

§

impl Send for udp_h

§

impl Sync for udp_h

§

impl Unpin for udp_h

§

impl UnwindSafe for udp_h

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/vlan_switch/struct.vlan_h.html b/vlan_switch/struct.vlan_h.html new file mode 100644 index 00000000..8380762c --- /dev/null +++ b/vlan_switch/struct.vlan_h.html @@ -0,0 +1,99 @@ +vlan_h in vlan_switch - Rust +

Struct vlan_switch::vlan_h

source ·
pub struct vlan_h {
+    pub valid: bool,
+    pub pcp: BitVec<u8, Msb0>,
+    pub dei: BitVec<u8, Msb0>,
+    pub vid: BitVec<u8, Msb0>,
+    pub ether_type: BitVec<u8, Msb0>,
+}

Fields§

§valid: bool§pcp: BitVec<u8, Msb0>§dei: BitVec<u8, Msb0>§vid: BitVec<u8, Msb0>§ether_type: BitVec<u8, Msb0>

Implementations§

source§

impl vlan_h

source

pub(crate) fn setValid(&mut self)

source

pub(crate) fn setInvalid(&mut self)

source

pub(crate) fn isValid(&self) -> bool

source

pub(crate) fn dump(&self) -> String

Trait Implementations§

source§

impl Checksum for vlan_h

source§

fn csum(&self) -> BitVec<u8, Msb0>

source§

impl Clone for vlan_h

source§

fn clone(&self) -> vlan_h

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 Debug for vlan_h

source§

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

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

impl Default for vlan_h

source§

fn default() -> vlan_h

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

impl Header for vlan_h

source§

fn new() -> Self

source§

fn set(&mut self, buf: &[u8]) -> Result<(), TryFromSliceError>

source§

fn size() -> usize

source§

fn set_valid(&mut self)

source§

fn set_invalid(&mut self)

source§

fn is_valid(&self) -> bool

source§

fn to_bitvec(&self) -> BitVec<u8, Msb0>

Auto Trait Implementations§

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
§

impl<T> Conv for T

§

fn conv<T>(self) -> T
where + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>
where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted. Read more
§

fn fmt_display(self) -> FmtDisplay<Self>
where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted. Read more
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>
where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted. Read more
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>
where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted. Read more
§

fn fmt_octal(self) -> FmtOctal<Self>
where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted. Read more
§

fn fmt_pointer(self) -> FmtPointer<Self>
where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted. Read more
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>
where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted. Read more
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>
where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted. Read more
§

fn fmt_list(self) -> FmtList<Self>
where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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.

+
§

impl<T> Pipe for T
where + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> R
where + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> R
where + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> R
where + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
where + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> R
where + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
where + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
where + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
where + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> R
where + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
where + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
where + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
where + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
where + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
where + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Self
where + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

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

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>
where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

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

§

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>,

§

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.
§

impl<V, T> VZip<V> for T
where + V: MultiLane<T>,

§

fn vzip(self) -> V

\ No newline at end of file diff --git a/x4c/all.html b/x4c/all.html new file mode 100644 index 00000000..2c7f44d9 --- /dev/null +++ b/x4c/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +

List of all items

Structs

Enums

Functions

\ No newline at end of file diff --git a/x4c/enum.Target.html b/x4c/enum.Target.html new file mode 100644 index 00000000..f0b6dbca --- /dev/null +++ b/x4c/enum.Target.html @@ -0,0 +1,17 @@ +Target in x4c - Rust +

Enum x4c::Target

source ·
pub enum Target {
+    Rust,
+    RedHawk,
+    Docs,
+}

Variants§

§

Rust

§

RedHawk

§

Docs

Trait Implementations§

source§

impl Clone for Target

source§

fn clone(&self) -> Target

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 ValueEnum for Target

source§

fn value_variants<'a>() -> &'a [Self]

All possible argument values, in display order.
source§

fn to_possible_value<'a>(&self) -> Option<PossibleValue<'a>>

The canonical argument value. Read more
§

fn from_str(input: &str, ignore_case: bool) -> Result<Self, String>

Parse an argument into Self.

Auto Trait Implementations§

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> 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,

§

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>,

§

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>,

§

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.
\ No newline at end of file diff --git a/x4c/fn.process_file.html b/x4c/fn.process_file.html new file mode 100644 index 00000000..656b4d37 --- /dev/null +++ b/x4c/fn.process_file.html @@ -0,0 +1,6 @@ +process_file in x4c - Rust +

Function x4c::process_file

source ·
pub fn process_file(
+    filename: Arc<String>,
+    ast: &mut AST,
+    opts: &Opts
+) -> Result<()>
\ No newline at end of file diff --git a/x4c/index.html b/x4c/index.html new file mode 100644 index 00000000..f4eda610 --- /dev/null +++ b/x4c/index.html @@ -0,0 +1,3 @@ +x4c - Rust +

Crate x4c

source ·

Structs§

Enums§

Functions§

\ No newline at end of file diff --git a/x4c/sidebar-items.js b/x4c/sidebar-items.js new file mode 100644 index 00000000..48871324 --- /dev/null +++ b/x4c/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["Target"],"fn":["process_file"],"struct":["Opts"]}; \ No newline at end of file diff --git a/x4c/struct.Opts.html b/x4c/struct.Opts.html new file mode 100644 index 00000000..24cece67 --- /dev/null +++ b/x4c/struct.Opts.html @@ -0,0 +1,45 @@ +Opts in x4c - Rust +

Struct x4c::Opts

source ·
pub struct Opts {
+    pub show_tokens: bool,
+    pub show_ast: bool,
+    pub show_pre: bool,
+    pub show_hlir: bool,
+    pub filename: String,
+    pub target: Target,
+    pub check: bool,
+    pub out: String,
+}

Fields§

§show_tokens: bool

Show parsed lexical tokens.

+
§show_ast: bool

Show parsed abstract syntax tree.

+
§show_pre: bool

Show parsed preprocessor info.

+
§show_hlir: bool

Show high-level intermediate representation info.

+
§filename: String

File to compile.

+
§target: Target

What target to generate code for.

+
§check: bool

Just check code, do not compile.

+
§out: String

Filename to write generated code to.

+

Trait Implementations§

source§

impl Args for Opts

source§

fn augment_args<'b>(__clap_app: Command<'b>) -> Command<'b>

Append to [Command] so it can instantiate Self. Read more
source§

fn augment_args_for_update<'b>(__clap_app: Command<'b>) -> Command<'b>

Append to [Command] so it can update self. Read more
source§

impl CommandFactory for Opts

source§

fn into_app<'b>() -> Command<'b>

Deprecated, replaced with CommandFactory::command
source§

fn into_app_for_update<'b>() -> Command<'b>

Deprecated, replaced with CommandFactory::command_for_update
§

fn command<'help>() -> App<'help>

Build a [Command] that can instantiate Self. Read more
§

fn command_for_update<'help>() -> App<'help>

Build a [Command] that can update self. Read more
source§

impl FromArgMatches for Opts

source§

fn from_arg_matches(__clap_arg_matches: &ArgMatches) -> Result<Self, Error>

Instantiate Self from [ArgMatches], parsing the arguments as needed. Read more
source§

fn from_arg_matches_mut( + __clap_arg_matches: &mut ArgMatches +) -> Result<Self, Error>

Instantiate Self from [ArgMatches], parsing the arguments as needed. Read more
source§

fn update_from_arg_matches( + &mut self, + __clap_arg_matches: &ArgMatches +) -> Result<(), Error>

Assign values from ArgMatches to self.
source§

fn update_from_arg_matches_mut( + &mut self, + __clap_arg_matches: &mut ArgMatches +) -> Result<(), Error>

Assign values from ArgMatches to self.
source§

impl Parser for Opts

§

fn parse() -> Self

Parse from std::env::args_os(), exit on error
§

fn try_parse() -> Result<Self, Error>

Parse from std::env::args_os(), return Err on error.
§

fn parse_from<I, T>(itr: I) -> Self
where + I: IntoIterator<Item = T>, + T: Into<OsString> + Clone,

Parse from iterator, exit on error
§

fn try_parse_from<I, T>(itr: I) -> Result<Self, Error>
where + I: IntoIterator<Item = T>, + T: Into<OsString> + Clone,

Parse from iterator, return Err on error.
§

fn update_from<I, T>(&mut self, itr: I)
where + I: IntoIterator<Item = T>, + T: Into<OsString> + Clone,

Update from iterator, exit on error
§

fn try_update_from<I, T>(&mut self, itr: I) -> Result<(), Error>
where + I: IntoIterator<Item = T>, + T: Into<OsString> + Clone,

Update from iterator, return Err on error.

Auto Trait Implementations§

§

impl RefUnwindSafe for Opts

§

impl Send for Opts

§

impl Sync for Opts

§

impl Unpin for Opts

§

impl UnwindSafe for Opts

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> 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, U> TryFrom<U> for T
where + U: Into<T>,

§

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>,

§

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.
\ No newline at end of file diff --git a/x4c_error_codes/all.html b/x4c_error_codes/all.html new file mode 100644 index 00000000..9c2d77af --- /dev/null +++ b/x4c_error_codes/all.html @@ -0,0 +1,2 @@ +List of all items in this crate +

List of all items

\ No newline at end of file diff --git a/x4c_error_codes/index.html b/x4c_error_codes/index.html new file mode 100644 index 00000000..d35fb466 --- /dev/null +++ b/x4c_error_codes/index.html @@ -0,0 +1,3 @@ +x4c_error_codes - Rust +

Crate x4c_error_codes

source ·
\ No newline at end of file diff --git a/x4c_error_codes/sidebar-items.js b/x4c_error_codes/sidebar-items.js new file mode 100644 index 00000000..5244ce01 --- /dev/null +++ b/x4c_error_codes/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {}; \ No newline at end of file