macro_rules! derive_deftly_template_KeySpecifier {
    (
        { $($driver:tt)* } [$($aoptions:tt)*] { $($future:tt)* }
        $($tpassthrough:tt)*
    ) => { ... };
    ([$chain0:path, $($chains:path,)*] [$($accum:tt)*] $($passthrough:tt)*) => { ... };
    ($($wrong:tt)*) => { ... };
}
Expand description

A helper for implementing KeySpecifiers.

Applies to a struct that has some static components (prefix, role), and a number of variable components represented by its fields.

Implements KeySpecifier etc.

Each field is either a path field (which becomes a component in the ArtiPath), or a denotator (which becomes part of the final component in the ArtiPath).

The prefix is the first component of the ArtiPath of the KeySpecifier.

The role should be the name of the key in the Tor Specifications. The lowercased role is used as the prefix of the last component of the ArtiPath of the specifier. The role is followed by the denotators of the key.

The denotator fields, if there are any, should be annotated with #[denotator].

The declaration order of the fields is important. The inner components of the ArtiPath of the specifier are built from the string representation of its path fields, taken in declaration order, followed by the encoding of its denotators, also taken in the order they were declared. As such, all path fields, must implement KeySpecifierComponent. and all denotators must implement KeySpecifierComponent. The denotators are separated from the rest of the path, and from each other, by + characters.

For example, a key specifier with prefix "foo" and role "bar" will have an ArtiPath of the form "foo/<field1_str>/<field2_str>/../bar[+<denotators>]".

A key specifier of this form, with denotators that encode to “d1” and “d2”, would look like this: "foo/<field1_str>/<field2_str>/../bar+d1+d2".

§Results of applying this macro

#[derive(Deftly)] #[derive_deftly(KeySpecifier)] struct SomeKeySpec ... generates:

  • impl KeySpecifier for SomeKeySpec
  • struct SomeKeySpecPattern, a derived struct which contains an Option for each field. None in the pattern means “any”.
  • impl KeySpecifierPattern for SomeKeySpecPattern
  • impl TryFrom<KeyPath> for SomeKeySpec`
  • Registration of an impl of KeyPathInfoExtractor (on a private unit struct SomeKeySpecInfoExtractor)

§Custom attributes

  • #[deftly(prefix)] (toplevel): Specifies the fixed prefix (the first path component). Must be a literal string.

  • #[deftly(role = "...")] (toplevel): Specifies the role - the initial portion of the leafname. This should be the name of the key in the Tor Specifications. Must be a literal string. This or the field-level #[deftly(role)] must be specified.

  • **[adhoc(role)] (field): Specifies that the role is determined at runtime. The field type must implement [KeyDenotator].

  • #[deftly(summary = "...")] (summary, mandatory): Specifies the summary; ends up as the summary field in KeyPathInfo. (See KeyPathInfoBuilder::summary().) Must be a literal string.

  • #[deftly(denotator)] (field): Designates a field that should be represented in the key file leafname, after the role.

  • #[deftly(ctor_path = "expression")] (toplevel): Specifies that this kind of key has a representation in C Tor keystores, and provides an expression for computing the path. The expression should have type impl Fn(&Self) -> CTorPath.

    If not specified, the generated KeySpecifier::ctor_path implementation will always return None.

  • #[deftly(fixed_path_component = "component")] (field): Before this field insert a fixed path component component. (Can be even used before a denotator component, to add a final fixed path component.)

This is a derive_deftly template. Do not invoke it directly. To use it, write: #[derive(Deftly)] #[derive_deftly(KeySpecifier)].