Skip to main content

Crate omitty

Crate omitty 

Source
Expand description

§omitty

A Rust procedural macro for generating type variants with omitted fields.

§Overview

omitty provides a simple way to create variants of your structs with specific fields omitted, similar to TypeScript’s Omit<> utility type. This is useful for creating public-facing types from internal types, API response types, or different permission-level views of your data.

§Features

  • On-demand generation - Types are created only when actually used via Omit! macro
  • Module-level attribute - Use #[omitty] on modules to enable on-demand type generation
  • Automatic derive - Generates Debug, Clone, Serialize, Deserialize, PartialEq, Eq
  • Serde compatible - Works seamlessly with serde for JSON/serialization
  • Type-safe - Compile-time guarantees for omitted fields
  • Automatic conversions - impl From<Original> for easy value creation
  • Generic support - Works with generic types and lifetimes

§Usage

§Basic Example

ⓘ
use omitty::omitty;

#[omitty]
mod api {
    #[derive(omitty::Omittable, Debug, Clone, serde::Serialize, serde::Deserialize)]
    pub struct User {
        pub id: u64,
        pub name: String,
        pub secret_token: String,
    }

    pub struct Member {
        pub user: Omit!(User, secret_token),
    }
}

// Use automatic conversion with .into()
let user = api::User { id: 1, name: "Alice".into(), secret_token: "secret".into() };
let member = api::Member { user: user.into() };

§Multiple Omitted Fields

ⓘ
use omitty::omitty;

#[omitty]
mod api {
    #[derive(omitty::Omittable, Debug, Clone, serde::Serialize, serde::Deserialize)]
    pub struct User {
        pub id: u64,
        pub name: String,
        pub email: String,
        pub password_hash: String,
        pub secret_token: String,
    }

    pub struct PublicProfile {
        pub user: Omit!(User, password_hash, secret_token, email),
    }

    pub struct AdminView {
        pub user: Omit!(User, secret_token),
    }
}

// Two types are generated on-demand:
// 1. __omitty__User::UserWithout_password_hashWithout_secret_tokenWithout_email
// 2. __omitty__User::UserWithout_secret_token

§Automatic Conversions

Each generated type includes an automatic From<Original> implementation:

ⓘ
let user = api::User {
    id: 42,
    name: "Alice".to_string(),
    secret_token: "secret".to_string(),
};

// Use .into() for automatic conversion
let public_user: api::__omitty__User::UserWithout_secret_token = user.into();

// Serialization works seamlessly
let json = serde_json::to_string(&public_user).unwrap();
// json: {"id":42,"name":"Alice"}

§Generated Type Naming Convention

  • Generated types are placed in a submodule: __omitty__<OriginalType>
  • Type names follow the pattern: <OriginalType>Without_<field1>Without_<field2>...
  • Example: Omit!(User, secret_token) → __omitty__User::UserWithout_secret_token
  • Generic parameters are preserved: Omit!(Data<T>, field) → __omitty__Data::DataWithout_field<T>

§Error Handling

  • Type not found: If Omit!(NonExistent, field) references a type not in scope, you’ll get a clear compile error: “cannot find type NonExistent”
  • Module-only attribute: #[omitty] can only be applied to inline modules with content
  • Struct-only derive: Omittable can only be derived for structs with named fields

Attribute Macros§

omitty

Derive Macros§

Omittable