restructed
A quick and easy way to create derivative models of your existing types without repeating yourself. Reduce boilerplate and automatically generate related structs with custom field subsets and transformations.
Features
- Reduce boilerplate: Generate multiple related structs from a single definition
- Flexible field selection: Include or exclude specific fields with
fields()andomit() - Automatic trait generation:
From<T>implementations between original and generated structs - Derive support: Apply derives to generated structs
- Multiple model types: Views, patches, and custom transformations
New features and roadmap are available here on GitHub.
Installation
Add restructed to your Cargo.toml:
[]
= "0.2"
Or run this command in your project directory:
Quick Start
Add the derive macro to your struct:
use Models;
Then add attributes for each model you want to generate:
// Subset without sensitive fields
// Optional fields for updates
This generates:
UserProfilestruct withid,username, andemailfieldsUserUpdatestruct withOption<String>fields forusernameandemail- Automatic
Fromimplementations for conversions
Model Types
#[view] - Field Subsets
Creates a struct containing a subset of the original fields. Perfect for API responses, database views, or public representations.
Arguments:
| Name | Description | Required | Type | Example |
|---|---|---|---|---|
name |
Name of the generated struct | Yes (first) | Identifier | UserProfile |
fields |
Fields to include | No | List | fields(id, username) |
omit |
Fields to exclude | No | List | omit(password, secret) |
derive |
Traits to derive | No | List | derive(Debug, Clone) |
preset |
Behavior preset to apply | No | String | preset = "read" |
attributes_with |
Attributes to inherit | No | String | attributes_with = "all" |
Note: Use either fields OR omit, not both.
Example:
// Usage
let user = User ;
let profile: UserProfile = user.into;
#[patch] - Optional Field Wrappers
Creates a struct where each field is wrapped in Option<T>. Ideal for partial updates, PATCH endpoints, or optional modifications.
Arguments:
| Name | Description | Required | Type | Example |
|---|---|---|---|---|
name |
Name of the generated struct | Yes (first) | Identifier | UserUpdate |
fields |
Fields to include | No | List | fields(username, email) |
omit |
Fields to exclude | No | List | omit(id, created_at) |
derive |
Traits to derive | No | List | derive(Debug, Serialize) |
preset |
Behavior preset to apply | No | String | preset = "write" |
attributes_with |
Attributes to inherit | No | String | attributes_with = "oai" |
option |
Alternative to Option<T> |
No | Type | option = MaybeUndefined |
skip_serializing_double_option |
Skip serializing None for Option<Option<T>> |
No | Boolean | skip_serializing_double_option = true |
Example:
// Usage
let update = UserUpdate ;
#[model] - Base Configuration
Defines default arguments applied to all generated models. This attribute doesn't generate structs itself but configures other model generators.
Sub-attributes:
base - Non-overridable Defaults
Arguments that are always applied and cannot be overridden by individual models.
// All models MUST derive Debug and Clone
defaults - Overridable Defaults
Arguments applied only when not specified by individual models.
// Applied unless overridden
Example:
// Inherits Debug + Clone + preset="read"
// Inherits Debug + Clone, overrides preset
Advanced Features
Presets
Presets apply common configurations automatically:
"none"(default): No special behavior"write"(requires 'openapi' feature): For writable fields- Removes
#[oai(read_only)]fields - Uses
MaybeUndefinedfor patch option type
- Removes
"read"(requires 'openapi' feature): For readable fields- Removes
#[oai(write_only)]fields - Uses
MaybeUndefinedfor patch option type
- Removes
Attribute Inheritance
Control which attributes are copied to generated structs:
-
"none"(default): No attributes copied -
"oai"(requires 'openapi' feature): Copy OpenAPI attributes -
"deriveless": Copy all attributes except derives -
"all": Copy all attributes, even dervies but they'll need to be on their own line (See below example) i.e.
Complete Example
Feature Flags
openapi - Poem OpenAPI Integration
Enables integration with the poem-openapi crate:
- Use
MaybeUndefined<T>instead ofOption<T>in patch models - Copy
#[oai(...)]attributes to generated structs - Respect
read_only/write_onlyattributes in presets
use Models;
Limitations
- Generic types: Currently doesn't support generic structs or enums (e.g.,
Struct<T>) - Enum support: Only works with structs, not enums
Contributions for these features are welcome!
License
See the project repository for license information.