| Crates.io | omni-schema |
| lib.rs | omni-schema |
| version | 0.1.1 |
| created_at | 2025-12-12 14:16:10.796832+00 |
| updated_at | 2025-12-12 14:29:31.751001+00 |
| description | Universal Schema Generator for Rust - One source of truth, multiple outputs |
| homepage | |
| repository | https://github.com/ddoemonn/omni-schema |
| max_upload_size | |
| id | 1981602 |
| size | 40,135 |
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.
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"] }
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 },
}
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);
}
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();
}
| 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 |
#[derive(Schema)]
#[schema(
description = "Documentation for the type",
rename = "CustomName",
rename_all = "camelCase",
deprecated
)]
pub struct MyType { /* ... */ }
#[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,
}
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"}
[dependencies]
omni-schema = { version = "0.1", features = ["all-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 |
| Feature | Description |
|---|---|
uuid-support |
UUID type support |
chrono-support |
DateTime type support |
url-support |
URL type support |
all-types |
All type support features |
| Feature | Description |
|---|---|
serde-compat |
Serde attribute compatibility |
full |
Everything enabled |
| 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 |
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,
}
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 | Description |
|---|---|
omni-schema |
Main library (re-exports) |
omni-schema-core |
Core types and format generators |
omni-schema-derive |
Proc-macro implementation |
Contributions are welcome! Please feel free to submit a Pull Request.