A quick and easy way to create derivative models of your existing types without repeating yourself all the damn time.
- Reduce number of structs you need to write
- Allows deriving on generated structs
- Allows generating multiple structs from one derive
- Automatically generates `From` traits for original <> generated structs
New features planned are available [here](https://github.com/NexRX/restructed/issues/1) on github. See below for examples of current usage & features.
# Usage
Add `restructed` to your project `Cargo.toml`:
```toml
restructed = "0.2"
```
alternatively, run this in the project directory.
```sh
cargo add restructed
```
Add the import and derive it on the target struct
```rust
#[derive(restructed::Models)]
struct User {
id: i32,
username: String
}
```
And then add attributes for each model you want to create.
```rust
#[derive(restructed::Models)]
#[view(UserId, fields(id))] // <-- Simple subset of the deriving structs field
#[patch(UserUpdatables, omit(id))] // <-- Wraps all fields with a Option type inside a new struct
struct User {
id: i32,
username: String,
}
```
Continue reading for the available models and their breakdowns and arguments in general.
# Models
These are arguments that can be applied to their respective attributes (i.e. `#[attr(args...)])`).
## `#[view]`
A model that generates a subset of the original/parent deriving `Model`. It is useful for creating things like RESTful APIs or database views.
| Argument Name | description | Required? | Type/Enum | Example |
|-----------------|----------------------------------------------------|------------|-------------------------|-----------------------------------|
| name | Name of the struct the generate | True+First | Identifier | `MyStruct` |
| **fields** or | Field names in the original structure to include | False | List(Ident) | `fields(field1, field2, ...)` |
| **omit** | Field names in the original structure to exclude | False | List(Ident) | `omit(field1, field2, ...)` |
| derive | Things to derive on the newly generated struct | False | List(Path) | `derive(Debug, thiserror::Error)` |
| preset | Behaviours and/or defaults to apply | False | none/write/read | `preset = "all"` |
| attributes_with | Attributes to inherit at both struct & field level | False | none/oai/deriveless/all | `attributes_with = "all"` |
```rust
#[derive(Clone, restructed::Models)]
#[view(UserProfile, omit(id, password))]
struct User {
id: i32, // Not in `UserProfile`
display_name: String,
bio: String,
extra: Option,
password: String, // Not in `UserProfile`
}
```
## `#[patch]`
A model that creates subsets of your data except each field's type is wrapped in a `Option` or a alternative type of Option implementation if specified. It is useful for creating RESTful API patch method types or database table patches where you only want to update fields if they were explicitly given (even to delete).
| Argument Name | description | Required? | Type/Enum | Example |
|-----------------|----------------------------------------------------|------------|-------------------------|-----------------------------------|
| name | Name of the struct the generate | True+First | Identifier | `MyStruct` |
| **fields** or | Field names in the original structure to include | False | List(Ident) | `fields(field1, field2, ...)` |
| **omit** | Field names in the original structure to exclude | False | List(Ident) | `omit(field1, field2, ...)` |
| derive | Things to derive on the newly generated struct | False | List(Path) | `derive(Debug, thiserror::Error)` |
| preset | Behaviours and/or defaults to apply | False | none/write/read | `preset = "all"` |
| attributes_with | Attributes to inherit at both struct and field level | False | none/oai/deriveless/all | `attributes_with = "all"` |
| option | A alternative to `Option` to wrap fields with | False | Option/MaybeUndefined | `option = MaybeUndefined` |
```rust
#[derive(Clone, restructed::Models)]
#[patch(UserUpdate, fields(display_name, bio, extra, password))]
struct User {
id: i32, // Not in `UserUpdate`
display_name: String, // Option in `UserUpdate`
bio: String, // Option in `UserUpdate`
extra: Option, // Option