1 unstable release
Uses new Rust 2024
| 0.1.0 | Dec 9, 2025 |
|---|
#58 in #elasticsearch
34 downloads per month
Used in elastic-mapping
30KB
605 lines
Procedural macros for the elastic-mapping crate.
This crate provides the #[derive(Document)] macro that automatically generates
Elasticsearch mapping implementations for Rust structs and enums.
You typically don't need to depend on this crate directly. Instead, use the
main elastic-mapping crate which re-exports the Document derive macro.
Example
use elastic_mapping::Document;
#[derive(Document)]
struct MyDocument {
title: String,
count: i64,
}
elastic-mapping
Generate Elasticsearch mapping definitions from Rust structs and enums using derive macros.
Features
- Derive macro for automatic mapping generation from Rust types
- Serde compatibility - respects
#[serde(rename)],#[serde(rename_all)],#[serde(flatten)]and enum representations - Enum support - handles externally tagged, internally tagged (
#[serde(tag = "...")]), and adjacently tagged (#[serde(tag = "...", content = "...")]) enums - Field annotations - configure analyzers, keyword fields, and other Elasticsearch-specific settings
- Optional feature flags - support for
chrono,url, anduuidtypes
Available Features
chrono- Adds support forchrono::DateTime<Utc>(mapped asdate)url- Adds support forurl::Url(mapped astext)uuid- Adds support foruuid::Uuid(mapped astext)full- Enables all optional features
Usage
Basic Example
use elastic_mapping::{Document, MappingObject};
use serde::Serialize;
#[derive(Debug, Serialize, Document)]
struct BlogPost {
title: String,
content: String,
published: bool,
views: i64,
}
fn main() {
let mapping = BlogPost::document_mapping();
println!("{}", serde_json::to_string_pretty(mapping.inner()).unwrap());
}
Output:
{
"mappings": {
"properties": {
"content": {
"type": "text"
},
"published": {
"type": "boolean"
},
"title": {
"type": "text"
},
"views": {
"type": "long"
}
}
}
}
Field Annotations
use elastic_mapping::{Document, MappingObject};
#[derive(Debug, Document)]
struct Article {
#[document(analyzer = "english")]
title: String,
#[document(keyword(index = false))]
internal_id: String,
#[document(keyword(ignore_above = 256))]
category: String,
}
Serde Compatibility
The macro respects serde attributes:
use elastic_mapping::{Document, MappingObject};
use serde::Serialize;
#[derive(Debug, Serialize, Document)]
#[serde(rename_all = "camelCase")]
struct UserProfile {
first_name: String,
last_name: String,
email_address: String,
}
// Field names will be mapped as: firstName, lastName, emailAddress
Nested Structures
use elastic_mapping::{Document, MappingObject};
#[derive(Debug, Document)]
struct Address {
street: String,
city: String,
country: String,
}
#[derive(Debug, Document)]
struct User {
name: String,
address: Address,
tags: Vec<String>,
}
Enum Support
Externally Tagged Enums
use elastic_mapping::{Document, MappingObject};
#[derive(Debug, Document)]
enum Event {
Created { id: String, timestamp: i64 },
Updated { id: String, changes: String },
Deleted { id: String },
}
Internally Tagged Enums
use elastic_mapping::{Document, MappingObject};
use serde::Serialize;
#[derive(Debug, Serialize, Document)]
#[serde(tag = "type")]
enum Message {
Text { content: String },
Image { url: String, width: u32, height: u32 },
}
Adjacently Tagged Enums
use elastic_mapping::{Document, MappingObject};
use serde::Serialize;
#[derive(Debug, Serialize, Document)]
#[serde(tag = "type", content = "data")]
enum Notification {
Email { to: String, subject: String },
SMS { phone: String, message: String },
Push { device_id: String, title: String },
}
Flatten Support
use elastic_mapping::{Document, MappingObject};
use serde::Serialize;
#[derive(Debug, Serialize, Document)]
struct Metadata {
created_at: i64,
updated_at: i64,
}
#[derive(Debug, Serialize, Document)]
struct Document {
title: String,
content: String,
#[serde(flatten)]
metadata: Metadata,
}
// Fields created_at and updated_at will be flattened into Document
With Optional Features
| Rust Type | Elasticsearch Type | Feature Flag |
|---|---|---|
chrono::DateTime<Utc> |
date |
chrono |
url::Url |
text |
url |
uuid::Uuid |
text |
uuid |
Available Attributes
Field-level #[document(...)] Attributes
analyzer = "analyzer_name"- Sets the analyzer for a text fieldkeyword(index = bool)- Adds a keyword subfield with index configurationkeyword(ignore_above = u32)- Adds a keyword subfield with ignore_above setting
Serde Attributes
The following serde attributes are respected:
#[serde(rename = "name")]- Rename a field or variant#[serde(rename_all = "case")]- Rename all fields or variants (supportscamelCase,kebab-case,snake_case,SCREAMING_SNAKE_CASE, etc.)#[serde(flatten)]- Flatten nested structure fields#[serde(tag = "...")]- Internally tagged enum representation#[serde(tag = "...", content = "...")]- Adjacently tagged enum representation
License
This project is licensed under the MIT License - see the LICENSE file for details.
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Dependencies
~1.3–2.1MB
~41K SLoC