Selectors
=========

All SwimOS connectors use the Recon model (encoded by the `swimos::model::Value` type) as a generic way to represent data. All lanes and downlinks used by connector agents have their generic parameters set to `Value`, for example `ValueLane<Value>`, `MapLane<Value, Value>`, etc. 

Typically, when a value is read from an external data source, it will be converted into the Recon model before being set into one of the connector's lanes or forwarded on to another agent. For connectors that deserialize from binary/text messages, this will typically by accomplished by a format described by `swimos_connector::config::format::DataFormat`. For a connector that reads from a row based data source, the conversion will likely be more ad hoc. Conversely, for an egress connector, values that result from events within the agent will be converted to the format required by the external sink.

Often, we may want to select some sub-component of the value that is produced. For example, we might want to extract an integer value from a named field of a record and then set that integer into a lane. To accomplish this, many connectors use selector expressions which are strings that describe how to select a component. There are four fundamental kinds of selector expression:

1. _Root selectors_: Incoming messages consist of one or more components (for example, a message may have both a key and a payload). The supported root selectors vary between connector implementations. These have names that consist of an identifier, preceded by a '$'. Examples of root selectors would be `$key` and `$payload`. Root selectors will select the entirety of the value associated with that component, if defined, or fail to match.
2. _Indexed selectors_: Indexed selectors select the value of an item within a record, selected by another selector, by index. If the value is not a record or does not have a sufficient number of items, the selector will not match. An indexed selector is specified by appending an index in brackets to another selector. For example, consider the selector `$root[2]`. If `$root` selects `{1, 2, 3, 4}`, this will select `3`.
3. _Attribute selectors_: Attribute selectors select the value of an attribute on a record, selected by another selector, by name. If the value is not a record or does not have an attribute with that name, the selector will not match. An attribute selector is specified by appending `.@name` to an existing selector, where `name` is the name of the attribute. For example, consider the selector `$root.@green`. If `$root` selects `@red(4) @green(5) @blue(0) {}`, this will select `5`.
4. _Slot selectors_: Slot selectors select the value of a slot in a record, selected by another selector, by name. If the value is not a record or does not have a slot with that name, the selector will not match. An attribute is specified by appending `.name` to an existing selector, where `name` is the name of the slot. For example, consider the selector `$root.green`. If `$root` selects `{ red: 4, green: 5, blue: 0}`, this will select `5`.

All selectors must start with a root selector and can be stacked arbitrarily. For example, `$root.first.@inner[5]` is a valid selector.