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:
Omittablecan only be derived for structs with named fields