elastic-mapping

Crates.ioelastic-mapping
lib.rselastic-mapping
version0.1.0
created_at2025-12-09 09:16:24.754227+00
updated_at2025-12-09 09:16:24.754227+00
descriptionGenerate Elasticsearch mapping definitions from Rust structs and enums using derive macros
homepagehttps://github.com/Reclamefolder/elastic-mapping
repositoryhttps://github.com/Reclamefolder/elastic-mapping
max_upload_size
id1975153
size57,006
(nils-degroot)

documentation

https://docs.rs/elastic-mapping

README

elastic-mapping

Crates.io Documentation License: MIT

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, and uuid types

Available Features

  • chrono - Adds support for chrono::DateTime<Utc> (mapped as date)
  • url - Adds support for url::Url (mapped as text)
  • uuid - Adds support for uuid::Uuid (mapped as text)
  • 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 field
  • keyword(index = bool) - Adds a keyword subfield with index configuration
  • keyword(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 (supports camelCase, 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.

Commit count: 0

cargo fmt