rok-search-macros 0.6.0

Derive macro for the rok-orm search Searchable trait
Documentation
  • Coverage
  • 100%
    2 out of 2 items documented0 out of 1 items with examples
  • Size
  • Source code size: 10.75 kB This is the summed size of all the files inside the crates.io package for this release.
  • Documentation size: 282.86 kB This is the summed size of all files generated by rustdoc for all configured targets
  • Ø build duration
  • this release: 8s Average build duration of successful builds.
  • all releases: 11s Average build duration of successful builds in releases after 2024-10-23.
  • Links
  • Homepage
  • Repository
  • crates.io
  • Dependencies
  • Versions
  • Owners
  • ateeq1999

rok-search-macros

Proc-macro crate providing #[derive(Searchable)] for rok-search.

Part of the Rok Framework — a full-stack Rust web framework built on Axum 0.8 and SQLx 0.8.

crates.io docs.rs MIT

Features

  • #[derive(Searchable)] — implements the Searchable trait for any struct
  • #[search(index = "...")] container attribute to name the search index
  • #[search(weight = "A"|"B"|"C"|"D")] field attribute for PostgreSQL FTS ranking
  • #[search(filterable)] field attribute to mark fields usable in filter expressions
  • #[search(skip)] field attribute to exclude a field from the search index
  • Zero runtime cost — all reflection happens at compile time

Installation

Do not add rok-search-macros directly. Use rok-search instead — it re-exports the derive macro.

[dependencies]
rok-search = { version = "0.2", features = ["meilisearch"] }

Usage

use rok_search::Searchable;

#[derive(Debug, serde::Serialize, serde::Deserialize, sqlx::FromRow, Searchable)]
#[search(index = "products")]
pub struct Product {
    pub id:          i64,

    /// Boosted to weight A — most important for ranking.
    #[search(weight = "A")]
    pub name:        String,

    /// Weight B — less important than name.
    #[search(weight = "B")]
    pub description: String,

    /// Included in the index document but not used for FTS ranking.
    #[search(filterable)]
    pub category:    String,

    /// Filterable numeric field — enables `price < 50` filter expressions.
    #[search(filterable)]
    pub price_cents: i64,

    /// Never sent to the search engine.
    #[search(skip)]
    pub internal_cost: i64,
}

Core API

The #[derive(Searchable)] macro generates an implementation of the Searchable trait:

pub trait Searchable: serde::Serialize + Send + Sync {
    /// The name of the search index (e.g. `"products"`).
    fn index_name() -> &'static str;

    /// The unique document ID used by the search engine.
    fn search_id(&self) -> i64;

    /// Field metadata: name, weight, filterable flag.
    fn search_fields() -> &'static [SearchField];

    /// Serialize this document into a JSON value for indexing.
    fn to_search_document(&self) -> serde_json::Value;
}

Integration

rok-search-macros is a private implementation detail of rok-search. The generated Searchable impl is consumed by SearchDriver::index, SearchDriver::query, and the ORM observer that keeps the index in sync with database writes.

If you need to implement Searchable manually (e.g. for a virtual document that combines multiple tables), you can do so by implementing the trait directly without the derive macro:

use rok_search::{Searchable, SearchField, FieldWeight};

impl Searchable for PostWithAuthor {
    fn index_name() -> &'static str { "posts" }
    fn search_id(&self) -> i64 { self.post_id }
    fn search_fields() -> &'static [SearchField] {
        &[
            SearchField { name: "title",       weight: FieldWeight::A, filterable: false },
            SearchField { name: "author_name", weight: FieldWeight::B, filterable: true  },
        ]
    }
    fn to_search_document(&self) -> serde_json::Value {
        serde_json::json!({
            "id":          self.post_id,
            "title":       self.title,
            "author_name": self.author_name,
        })
    }
}

License

MIT