omitty
A Rust procedural macro for generating type variants with omitted fields, on-demand.
Features
- On-demand generation - Types created only when used via
Omit! macro
- Module-level attribute - Use
#[omitty] on modules
- Automatic conversions -
impl From<Original> generated automatically
- Type-safe - Compile-time guarantees
- Serde compatible - Works seamlessly with serialization
- Generic support - Preserves type parameters and lifetimes
Installation
[dependencies]
omitty = "0.1.0"
serde = { version = "1.0", features = ["derive"] }
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 PublicUser {
pub user: Omit!(User, secret_token),
}
}
fn main() {
let user = api::User {
id: 42,
name: "Alice".to_string(),
secret_token: "super_secret".to_string(),
};
let public = api::PublicUser {
user: user.into(), };
let json = serde_json::to_string(&public.user).unwrap();
}
Multiple Omitted Fields
#[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),
}
}
Generic Types
#[omitty]
mod api {
#[derive(omitty::Omittable, Debug, Clone)]
pub struct User<T> {
pub id: u64,
pub name: String,
pub secret: String,
pub metadata: T,
}
pub struct PublicUser<T> {
pub user: Omit!(User<T>, secret),
}
}
How It Works
- Mark your module with
#[omitty]
- Derive
Omittable on your struct
- Use
Omit!(Type, field1, field2, ...) in field types
- Types are generated automatically as
__omitty__Type::TypeWithout_field1_field2
impl From<Type> is generated for easy conversion
Generated Code
For Omit!(User, secret_token), omitty generates:
pub mod __omitty__User {
pub struct UserWithout_secret_token {
pub id: u64,
pub name: String,
}
impl From<super::User> for UserWithout_secret_token {
fn from(value: super::User) -> Self {
Self { id: value.id, name: value.name }
}
}
}
Benefits
- Zero boilerplate - No manual type definitions
- DRY principle - Single source of truth
- Type safety - Compile-time checks
- Performance - Zero runtime overhead
- Flexibility - Mix and match omitted fields
License
MIT OR Apache-2.0