# omitty
A Rust procedural macro for generating type variants with omitted fields.
## Features
- **Simple syntax** - Generate variants with just `#[omit_variant(VariantName, field1, field2)]`
- **Automatic derive** - Automatically generates Debug, Clone, Serialize, Deserialize, PartialEq, Eq
- **Serde compatible** - Works seamlessly with serde for JSON/serialization
- **Type-safe** - Compile-time guarantees for omitted fields
## Installation
Add this to your `Cargo.toml`:
```toml
[dependencies]
omitty = "0.1.0"
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
```
## Usage
### Basic Example
```rust
use omitty::OmittableType;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, OmittableType)]
#[omit_variant(UserPublic, secret_token)]
pub struct User {
pub id: String,
pub username: String,
pub secret_token: String,
}
```
This generates a new `UserPublic` struct with only `id` and `username`:
```rust
pub struct UserPublic {
pub id: String,
pub username: String,
}
```
### Multiple Omitted Fields
```rust
use omitty::OmittableType;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, OmittableType)]
#[omit_variant(UserPublic, secret_token, password, internal_id, email)]
pub struct User {
pub id: String,
pub username: String,
pub secret_token: String,
pub password: String,
pub internal_id: i64,
pub email: String,
}
```
### Multiple Variants
```rust
use omitty::OmittableType;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, OmittableType)]
#[omit_variant(UserPublic, secret_token, password, email)]
#[omit_variant(UserMinimal, secret_token, password, email, bio, avatar_url)]
pub struct User {
pub id: String,
pub username: String,
pub secret_token: String,
pub password: String,
pub email: String,
pub bio: String,
pub avatar_url: String,
}
```
This generates both `UserPublic` and `UserMinimal` structs with different fields omitted.
### Real-World Example: Discord-like API
```rust
use omitty::OmittableType;
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize, OmittableType)]
#[omit_variant(UserPublic, secret_token)]
pub struct User {
pub id: String,
pub username: String,
pub secret_token: String,
}
#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct Member {
pub user: UserPublic,
pub nick: String,
}
fn main() {
let json = r#"{
"user": {
"id": "123",
"username": "meetzli"
},
"nick": "Meetz"
}"#;
let member: Member = serde_json::from_str(json).unwrap();
println!("Username: {}", member.user.username);
println!("Nick: {}", member.nick);
}
```
## Syntax
```rust
#[omit_variant(VariantName, field1, field2, field3, ...)]
```
- **VariantName**: The name of the generated struct (identifier, not a string)
- **field1, field2, ...**: Names of fields to omit from the original struct
## Generated Derives
All generated variants automatically derive:
- `Debug`
- `Clone`
- `serde::Serialize`
- `serde::Deserialize`
- `PartialEq`
- `Eq`
## Use Cases
- **API responses** - Return public user data without sensitive fields
- **Database models** - Create DTO variants without internal fields
- **Multi-tier data access** - Different permission levels see different fields
- **Caching** - Store lightweight versions of structs
- **Testing** - Create test fixtures with subset of data
## Error Messages
The macro provides clear, actionable error messages:
```rust
// Error: Omittable can only be derived for structs with named fields (not tuple structs or unit structs)
// Error: field type must be a path type (e.g., User, MyType). Complex types like references, arrays, or tuples are not supported
// Error: missing variant name as first argument in omit_variant attribute. Usage: #[omit_variant(VariantName, field1, field2, ...)]
```
## License
MIT OR Apache-2.0