omni-schema 0.1.1

Universal Schema Generator for Rust - One source of truth, multiple outputs
Documentation
//! # 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.
//!
//! ## Quick Start
//!
//! Add `omni-schema` to your `Cargo.toml`:
//!
//! ```toml
//! [dependencies]
//! omni-schema = { version = "0.1", features = ["all-formats"] }
//! ```
//!
//! Then use the `Schema` derive macro:
//!
//! ```rust,ignore
//! 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,
//!
//!     pub tags: Vec<String>,
//! }
//!
//! #[derive(Schema)]
//! pub enum Status {
//!     Active,
//!     Inactive,
//!     Suspended { reason: String },
//! }
//! ```
//!
//! Generate schemas:
//!
//! ```rust,ignore
//! use omni_schema::prelude::*;
//!
//! // Generate JSON Schema
//! let json_schema = User::json_schema();
//!
//! // Generate TypeScript types
//! let typescript = User::typescript_type();
//!
//! // Generate GraphQL SDL
//! let graphql = User::graphql_sdl();
//!
//! // Generate Protocol Buffers
//! let proto = User::proto_definition();
//! ```
//!
//! ## Batch Export with Registry
//!
//! For exporting multiple types together:
//!
//! ```rust,ignore
//! use omni_schema::{Schema, SchemaRegistry};
//!
//! let registry = SchemaRegistry::new()
//!     .register::<User>()
//!     .register::<Status>()
//!     .with_title("My API")
//!     .with_version("1.0.0");
//!
//! // Export to files
//! registry.export_json_schema("./schemas/json/").unwrap();
//! registry.export_typescript("./schemas/types.ts").unwrap();
//! registry.export_graphql("./schemas/schema.graphql").unwrap();
//! registry.export_proto("./schemas/models.proto").unwrap();
//! ```
//!
//! ## Feature Flags
//!
//! - `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
//! - `uuid-support` - UUID type support
//! - `chrono-support` - DateTime type support
//! - `url-support` - URL type support
//! - `serde-compat` - Serde attribute compatibility
//! - `full` - Everything enabled

pub use omni_schema_derive::Schema;

pub use omni_schema_core::{
    Schema as SchemaImpl,
    SchemaRegistry,
    SchemaError, SchemaResult,
    types::{
        EnumDefinition, EnumRepresentation, EnumVariant, FieldDefinition,
        NewtypeDefinition, PrimitiveType, SchemaDefinition, SchemaType,
        StructDefinition, StructField, TypeReference, VariantData,
    },
    attributes::{
        EnumAttribute, FieldAttribute, RenameRule, SchemaAttributes,
        TypeAttribute, VariantAttribute,
    },
    ExternalSchema, FlattenableSchema,
};

/// Format-specific generators for advanced usage.
pub mod formats {

    #[cfg(feature = "json-schema")]
    pub use omni_schema_core::formats::json_schema;

    #[cfg(feature = "openapi")]
    pub use omni_schema_core::formats::openapi;

    #[cfg(feature = "graphql")]
    pub use omni_schema_core::formats::graphql;

    #[cfg(feature = "protobuf")]
    pub use omni_schema_core::formats::protobuf;

    #[cfg(feature = "typescript")]
    pub use omni_schema_core::formats::typescript;

    #[cfg(feature = "avro")]
    pub use omni_schema_core::formats::avro;

    pub use omni_schema_core::formats::format_ids;
    pub use omni_schema_core::formats::utils;
}

pub use omni_schema_core::registry::RegistryConfig;

#[cfg(feature = "uuid-support")]
pub use uuid;

#[cfg(feature = "chrono-support")]
pub use chrono;

#[cfg(feature = "url-support")]
pub use url;

#[cfg(feature = "serde-compat")]
pub use serde;

pub use serde_json;

/// Prelude module for convenient imports.
///
/// ```rust,ignore
/// use omni_schema::prelude::*;
/// ```
pub mod prelude {
    pub use super::Schema;
    pub use omni_schema_core::{Schema as SchemaImpl, SchemaRegistry};

    #[cfg(feature = "json-schema")]
    pub use omni_schema_core::formats::json_schema;

    #[cfg(feature = "typescript")]
    pub use omni_schema_core::formats::typescript;

    #[cfg(feature = "graphql")]
    pub use omni_schema_core::formats::graphql;

    #[cfg(feature = "protobuf")]
    pub use omni_schema_core::formats::protobuf;

    #[cfg(feature = "openapi")]
    pub use omni_schema_core::formats::openapi;

    #[cfg(feature = "avro")]
    pub use omni_schema_core::formats::avro;
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_schema_definition_creation() {
        let def = SchemaDefinition::new(
            "TestType",
            SchemaType::Primitive(PrimitiveType::String),
        )
        .with_description("A test type");

        assert_eq!(def.name, "TestType");
        assert!(def.description.is_some());
    }

    #[test]
    fn test_registry_creation() {
        let registry = SchemaRegistry::new()
            .with_title("Test API")
            .with_version("1.0.0");

        assert_eq!(registry.config().title, Some("Test API".to_string()));
        assert_eq!(registry.config().version, Some("1.0.0".to_string()));
    }

    #[test]
    fn test_struct_definition() {
        let struct_def = StructDefinition::new()
            .with_field(
                "name",
                StructField::new(
                    SchemaType::Primitive(PrimitiveType::String),
                    "name",
                )
                .with_description("The name field"),
            );

        assert_eq!(struct_def.fields.len(), 1);
        assert!(struct_def.fields.contains_key("name"));
    }

    #[test]
    fn test_enum_definition() {
        let enum_def = EnumDefinition::new(EnumRepresentation::External)
            .with_variant(EnumVariant::unit("Active"))
            .with_variant(EnumVariant::unit("Inactive"));

        assert_eq!(enum_def.variants.len(), 2);
        assert!(enum_def.is_simple_enum());
    }
}