omni-schema

Crates.ioomni-schema
lib.rsomni-schema
version0.1.1
created_at2025-12-12 14:16:10.796832+00
updated_at2025-12-12 14:29:31.751001+00
descriptionUniversal Schema Generator for Rust - One source of truth, multiple outputs
homepage
repositoryhttps://github.com/ddoemonn/omni-schema
max_upload_size
id1981602
size40,135
ozer (ddoemonn)

documentation

README

🦀 Omni-Schema

Universal Schema Generator for Rust - One source of truth, multiple outputs.

omni-schema generates multiple schema formats from a single Rust struct/enum definition using derive macros. Define your types once, export to JSON Schema, OpenAPI, GraphQL, Protocol Buffers, TypeScript, and Avro.

✨ Features

  • One Source of Truth: Define your types once in Rust, generate schemas for any format
  • Multiple Output Formats: JSON Schema, OpenAPI 3.1, GraphQL SDL, Protocol Buffers, TypeScript, Avro
  • Serde Compatible: Attribute syntax mirrors serde for easy adoption
  • Rich Validation: Support for constraints like min/max length, patterns, ranges
  • Zero Runtime Overhead: Schema generation happens on-demand
  • Incremental Adoption: Enable only the formats you need via feature flags

📦 Installation

Add omni-schema to your Cargo.toml:

[dependencies]
omni-schema = "0.1"

Or with specific features:

[dependencies]
omni-schema = { version = "0.1", features = ["all-formats"] }

🚀 Quick Start

use omni_schema::Schema;
use std::collections::HashMap;

#[derive(Schema)]
#[schema(description = "A user in the system")]
pub struct User {
    #[schema(description = "Unique identifier")]
    pub id: u64,

    #[schema(min_length = 1, max_length = 100)]
    pub name: String,

    #[schema(format = "email")]
    pub email: String,

    #[schema(minimum = 0, maximum = 150)]
    pub age: Option<u8>,

    pub status: Status,

    pub tags: Vec<String>,

    pub metadata: HashMap<String, String>,
}

#[derive(Schema)]
#[schema(description = "User account status")]
pub enum Status {
    Active,
    Inactive,
    #[schema(description = "User is temporarily suspended")]
    Suspended { reason: String },
}

Generate Schemas

use omni_schema::prelude::*;

fn main() {
    // Generate JSON Schema
    let json_schema = User::json_schema();
    println!("{}", json_schema);

    // Generate TypeScript types
    let typescript = User::typescript_type();
    println!("{}", typescript);

    // Generate GraphQL SDL
    let graphql = User::graphql_sdl();
    println!("{}", graphql);

    // Generate Protocol Buffers
    let proto = User::proto_definition();
    println!("{}", proto);

    // Generate OpenAPI schema
    let openapi = User::openapi_schema();
    println!("{}", openapi);

    // Generate Avro schema
    let avro = User::avro_schema();
    println!("{}", avro);
}

📦 Batch Export with Registry

For exporting multiple types together:

use omni_schema::{Schema, SchemaRegistry};

fn main() {
    let registry = SchemaRegistry::new()
        .register::<User>()
        .register::<Status>()
        .register::<Order>()
        .with_title("My API")
        .with_description("Schema definitions for My API")
        .with_version("1.0.0")
        .with_namespace("com.example.api");

    // Validate all types
    registry.validate().expect("Schema validation failed");

    // Export to files
    registry.export_json_schema("./schemas/json/").unwrap();
    registry.export_openapi("./schemas/openapi.yaml").unwrap();
    registry.export_graphql("./schemas/schema.graphql").unwrap();
    registry.export_proto("./schemas/models.proto").unwrap();
    registry.export_typescript("./schemas/types.ts").unwrap();
    registry.export_avro("./schemas/avro/").unwrap();

    // Or export all at once
    registry.export_all("./schemas/").unwrap();
}

📋 Supported Output Formats

Feature Format Description
json-schema JSON Schema Draft 2020-12 compliant
openapi OpenAPI 3.1 Component schemas for REST APIs
graphql GraphQL SDL Type definitions for GraphQL
protobuf Protocol Buffers Proto3 message definitions
typescript TypeScript Type definitions (.d.ts)
avro Apache Avro Schema for Avro serialization

🏷️ Attributes

Type-level Attributes

#[derive(Schema)]
#[schema(
    description = "Documentation for the type",
    rename = "CustomName",
    rename_all = "camelCase",
    deprecated
)]
pub struct MyType { /* ... */ }

Field-level Attributes

#[derive(Schema)]
pub struct User {
    #[schema(description = "Field documentation")]
    pub name: String,

    #[schema(min_length = 1, max_length = 100)]
    pub username: String,

    #[schema(minimum = 0, maximum = 150)]
    pub age: u8,

    #[schema(pattern = r"^\d{3}-\d{3}-\d{4}$")]
    pub phone: String,

    #[schema(format = "email")]
    pub email: String,

    #[schema(deprecated)]
    pub old_field: String,

    #[schema(skip)]
    pub internal: String,

    #[schema(flatten)]
    pub metadata: Metadata,

    #[schema(nullable)]
    pub optional_value: String,
}

Enum Representation

Supports all serde enum representations:

// Externally tagged (default)
#[derive(Schema)]
pub enum External {
    Variant { field: String }
}
// Output: {"Variant": {"field": "value"}}

// Internally tagged
#[derive(Schema)]
#[schema(tag = "type")]
pub enum Internal {
    Variant { field: String }
}
// Output: {"type": "Variant", "field": "value"}

// Adjacently tagged
#[derive(Schema)]
#[schema(tag = "type", content = "data")]
pub enum Adjacent {
    Variant { field: String }
}
// Output: {"type": "Variant", "data": {"field": "value"}}

// Untagged
#[derive(Schema)]
#[schema(untagged)]
pub enum Untagged {
    Variant { field: String }
}
// Output: {"field": "value"}

🔧 Feature Flags

[dependencies]
omni-schema = { version = "0.1", features = ["all-formats"] }

Output Formats

Feature Description
json-schema JSON Schema generation (default)
openapi OpenAPI 3.1 generation
graphql GraphQL SDL generation
protobuf Protocol Buffers generation
typescript TypeScript type generation
avro Apache Avro schema generation
all-formats All format generators

Type Support

Feature Description
uuid-support UUID type support
chrono-support DateTime type support
url-support URL type support
all-types All type support features

Integration

Feature Description
serde-compat Serde attribute compatibility
full Everything enabled

📊 Type Mappings

Rust Type JSON Schema TypeScript GraphQL Protobuf Avro
bool boolean boolean Boolean bool boolean
i8/i16/i32 integer number Int int32 int
i64 integer number BigInt int64 long
u8/u16/u32 integer number Int uint32 int
u64 integer number BigInt uint64 long
f32/f64 number number Float float/double float/double
String string string String string string
Option<T> oneOf [T, null] T | null T (nullable) optional T union [null, T]
Vec<T> array T[] [T!]! repeated T array
HashSet<T> array (unique) Set<T> [T!]! repeated T array
HashMap<K,V> object Record<K,V> JSON map<K,V> map
uuid::Uuid string (uuid) string ID string string (uuid)
chrono::DateTime string (date-time) string DateTime string string

🤝 Serde Compatibility

omni-schema uses attribute syntax that mirrors serde:

use serde::{Serialize, Deserialize};
use omni_schema::Schema;

#[derive(Serialize, Deserialize, Schema)]
#[serde(rename_all = "camelCase")]
#[schema(rename_all = "camelCase")]
pub struct User {
    #[serde(rename = "userId")]
    #[schema(rename = "userId")]
    pub user_id: u64,

    pub display_name: String,

    #[serde(skip)]
    #[schema(skip)]
    pub internal_field: String,
}

📖 Examples

Run the included examples:

# Basic usage example
cargo run --example basic --features "all-formats"

# Serde compatibility example
cargo run --example serde_compat --features "json-schema serde-compat"

📁 Crate Structure

Crate Description
omni-schema Main library (re-exports)
omni-schema-core Core types and format generators
omni-schema-derive Proc-macro implementation

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Commit count: 0

cargo fmt