Something went wrong

Thank you for being patient! We're working hard on resolving the issue

RowKeySchema derive DSL - Lona Docs Log in

RowKeySchema derive DSL

The #[derive(RowKeySchema)] proc-macro lives in tento-lona-connector-macros. Hosts use it to wire a set of reserved rowkey patterns to provider Row impls.

Minimal example

use tento_lona_connector::RowKeySchema;

#[derive(RowKeySchema)]
#[rowkey {
  [integration = ::tento_garmin::connector::Garmin] {
    ":~garmin:{authId}" {
      ":sleep" {
        get
        ":logs" { get }
      }
      ":stress" {
        get
        ":logs" { get }
      }
    }
  }

  [integration = ::tento_google::connector::GoogleCalendar] {
    ":~google:{authId}:calendar:{calId}" {
      ":events" { get, post, delete }
      ":events:freebusy" { get }
    }
  }
}]
pub struct RowKeys;

DSL grammar

Root        := Item*
Item        := Resource | AttrBlock
Resource    := LitStr "{" (Method ","? | Item)* "}"
AttrBlock   := "[" Attr ("," Attr)* "]" "{" Item* "}"
Attr        := "integration" "=" ExprPath
             | "guard"       "=" ExprPath
Method      := "get" | "post" | "patch" | "delete"
  • LitStr is the rowkey path segment, e.g. ":~garmin:{authId}".
  • Method declares which verbs the row handles.
  • AttrBlock wraps one or more Items with shared [integration = ...] and/or [guard = ...] settings.

Nested Resource items inherit the parent's path prefix — ":~garmin:{authId}" { ":sleep" { get } } registers the row ":~garmin:{authId}:sleep" for GET.

Per-block guards

Some rowkeys are operator-only. Wrap them in an AttrBlock with a guard:

#[rowkey {
  [
    integration = ::tento_weather::connector::Weather,
    guard = crate::guards::weather_operator,
  ] {
    ":~weather:{locationId}" { get }
  }
}]
pub struct RowKeys;

guard is a path to a fn(&dyn RowKeyAuthProvider, &RowKeyRequestCtx) -> bool.

What the macro emits

For each declared row + verb pair the macro emits:

  • A zero-sized RouteKey marker per row (binds the user-written Row impl + the derived PROVIDER_ID const).
  • A RowKeySchemaEntry registered into the schema's schemas() slice.
  • The impl RowKeySchema body with type Entry = RowKeySchemaEntry; fn schemas() { … }.

The host's matcher (match_key::<RowKeys>(lookup_key, method)) walks this slice, finds the matching pattern, extracts path params, and returns the entry plus a typed HandlerParams map.

Conditional compilation

AttrBlocks accept outer #[cfg(...)], so you can feature-gate provider blocks:

#[rowkey {
  #[cfg(feature = "wearables")]
  [integration = ::tento_garmin::connector::Garmin] {
    ":~garmin:{authId}:sleep" { get }
  }
}]
pub struct RowKeys;

Useful for builds that ship subsets of providers.