crates.io ↗

iet-db-macros

tooling tooling official

Derives entity metadata used by the TimescaleDB repository machinery.

CoreFeaturesIntegrationsStacksTooling
Used byiet-auth-acl-timescaleiet-auth-basic-timescaleiet-auth-identity-timescaleiet-auth-profiles-timescaleiet-auth-rbac-timescaleiet-auth-revocations-timescaleiet-auth-session-timescale
iet-db-macrostoolingEntity derive macros
Depends onnothing — it stands alone

How to use it

#[derive(Persistent)] reads a struct's #[persistent(...)] attributes to emit the iet_core::persistence::Persistent metadata used to generate DDL and queries (table, columns, keys, defaults, checks, indexes, foreign keys). #[derive(TimescaleEntity)] adds row decoding plus a generated field enum for typed filters and write mappings. Both are attribute-driven and expect real column types (String, Uuid, i64, bool, DateTime, or an explicit kind).

rust
// crates/integrations/iet-auth-session-timescale/src/entity.rs
use iet_db_macros::Persistent;

#[derive(Persistent)]
#[persistent(table = "fw_auth_sessions", hard_delete)]
#[persistent(foreign_key(name = "auth_session_subject", columns = "subject",
    references = "fw_auth_identities", referenced_columns = "id"))]
pub struct Session {
    #[persistent(primary_key, kind = "bytea")]
    pub digest: Vec<u8>,
    pub subject: uuid::Uuid,
    pub expires_at_ms: i64,
}

Combine both derives when you want typed filters; from examples/htmx-starter/crates/project-impl-timescale/src/entity.rs:

rust
// examples/htmx-starter/crates/project-impl-timescale/src/entity.rs
#[derive(iet_db_macros::Persistent, iet_db_macros::TimescaleEntity)]
#[persistent(table = "app_projects", hard_delete)]
#[entity(fields = ProjectField)]
pub(crate) struct ProjectEntity {
    pub id: i64,
    #[field(operators = "Equal")]
    pub owner: uuid::Uuid,
    pub name: String,
}
  • time_column + chunk_seconds declare a TimescaleDB hypertable; soft deletes add deleted_at unless hard_delete is set.
  • #[field(operators = "...")] whitelists Equal, Less, Contains, In, IsNull, and friends; without it non-writable fields are skipped.

How it works

Persistent walks the #[persistent(...)] attributes and emits the iet_core::persistence::Persistent metadata constants; TimescaleEntity reads #[entity(fields = ...)] and #[field(...)] to emit row decoding and a generated field enum implementing the query traits.

flowchart LR
  P["struct with persistent attributes"] --> DP["derive Persistent"]
  DP --> IP["impl iet_core persistence Persistent"]
  IP --> C["TABLE / COLUMNS / PRIMARY_KEY / INDEXES / FOREIGN_KEYS"]
  E["struct with entity and field attributes"] --> DE["derive TimescaleEntity"]
  DE --> IE["impl Entity and EntityRow"]
  DE --> FE["generated field enum"]
  FE --> FI["Column / WriteField / EntityFields / FilterField"]

What it implements

  • Concrete mechanism; see the public API below.

What's inside

Modules

  • src/entity.rs
  • src/lib.rs
  • src/persistent.rs

Public API

(root)

  • pub fn entity(input: proc_macro::TokenStream) -> proc_macro::TokenStream
  • pub fn persistent(input: proc_macro::TokenStream) -> proc_macro::TokenStream

entity

  • pub fn expand(input: TokenStream) -> TokenStream

persistent

  • pub fn expand(input: TokenStream) -> TokenStream

Depends on

  • No other framework crate: it stands alone.

External crates: proc-macro2, quote, syn

Used by

In this repository

  • examples/htmx-starter
  • examples/skills-only-app
  • examples/skills-only-app-task-tracker

Source: crates/macros/iet-db-macros