2 releases

0.1.1 Jan 19, 2025
0.1.0 Jan 18, 2025

#279 in Procedural macros

Download history 206/week @ 2025-01-14 43/week @ 2025-01-21

249 downloads per month
Used in battler-wamprat

MIT license

305KB
7K SLoC

battler-wamprat-uri

Latest Version

battler-wamprat-uri is a utility crate for battler-wamprat. It provides a procedural macro for dynamically matching URIs for WAMP subscriptions and procedure registrations.


lib.rs:

battler-wamprat-uri

battler-wamprat-uri is a utility crate for battler-wamprat. It provides a procedural macro for dynamically matching URIs for WAMP subscriptions and procedure registrations.

Pattern-based subscriptions and procedure registrations can be complex. They provide an additional avenue of input for WAMP messages, outside the arguments and arguments_keyword fields expressed by battler_wamprat_message::WampApplicationMessage types.

For example, a callee can register a procedure on the wildcard URI com.test.add..v2. A caller can then call this procedure using any URI that matches this pattern. One caller may call com.test.add.integers.v2 while another may call com.test.add.strings.v2. The wildcard URI component (in this case, integers or strings) is likely very important to the callee!

This crate provides runtime type checking and pattern matching to incoming and outgoing WAMP URI patterns through the WampUriMatcher derive macro. A URI matcher can be thought of as a glorified regular expression: each wildcard component is a named capture group that can be referenced after matching. The end result is that URIs going out from a peer can be formatted automatically, and URIs coming into a peer can be pattern matched, allowing the extracted URI components to be easily read by application logic.

Basic Usage

A struct using the WampUriMatcher derive macro must have a uri attribute. The URI describes the wildcard pattern, which is used for formatting outgoing URIs and matching incoming URIs.

In the simplest case, a struct with no fields can match a static URI:

use battler_wamprat_uri::WampUriMatcher;

#[derive(WampUriMatcher)]
#[uri("com.test.add")]
struct AddUri {}

For each field you add, that field must be represented in the URI pattern. Otherwise, the struct would be impossible to construct for incoming URIs.

use battler_wamprat_uri::WampUriMatcher;

#[derive(WampUriMatcher)]
#[uri("com.test.add.{name}.v2")]
struct AddUri {
    name: String,
}

Each struct field must be convertible to and from a string, using Display and FromStr respectively.

use battler_wamprat_uri::WampUriMatcher;

#[derive(WampUriMatcher)]
#[uri("com.test.add.{name}.{count}")]
struct AddUri {
    name: String,
    count: u64,
}

Advanced Features

Prefix Matching

In some cases, a URI pattern may need to match in prefix form. Prefix matching is only possible if the last field in the struct is marked with the rest attribute. This attribute requires that an iterator of Strings can be collected into its type.

use battler_wamprat_uri::WampUriMatcher;

#[derive(WampUriMatcher)]
#[uri("com.test.fn.{a}.{rest}")]
struct PrefixUri {
    a: String,
    #[rest]
    rest: Vec<String>,
}

Field Repetition

Fields can be repeated in the URI pattern. The first use of the field will be treated as the source of truth, and all later uses of the field must match this first value.

use battler_wamprat_uri::WampUriMatcher;

#[derive(WampUriMatcher)]
#[uri("com.test.fn.{a}.{b}.{a}")]
struct RepeatedUri {
    a: u64,
    b: u64,
}

Regular Expression Component Matching

In most cases, struct fields should be isolated to their own URI components for simplicity. However, this is not a strict requirement of the URI matcher macro.

Strings and struct fields can be combined into the same URI component. If this is done, the URI pattern matching is less enforceable on the router, but the peer will still validate and match the URI as expected.

use battler_wamprat_uri::WampUriMatcher;

#[derive(WampUriMatcher)]
#[uri("com.test.math.{a}log{b}")]
struct RegExUri {
    a: u64,
    b: u64,
}

Note that in the above case, the URI registered on the router will be the wildcard com.test.math., so the last component can be matched by any string. However, the RegExUri type will enforce the additional restrictions. For instance, the URI com.test.math.abc will be rejected by the peer, while com.test.math.2log12 will be accepted.

Note: URI such as the one above will generate a dependency on the regex crate.

Dependencies

~16–27MB
~486K SLoC