Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/halsekiraika/destructure
Automation of Destructure Pattern
https://github.com/halsekiraika/destructure
procedural-macro rust-lang utility
Last synced: 10 days ago
JSON representation
Automation of Destructure Pattern
- Host: GitHub
- URL: https://github.com/halsekiraika/destructure
- Owner: HalsekiRaika
- License: apache-2.0
- Created: 2023-01-04T06:28:53.000Z (almost 2 years ago)
- Default Branch: master
- Last Pushed: 2024-01-20T15:09:17.000Z (10 months ago)
- Last Synced: 2024-10-13T14:28:29.651Z (25 days ago)
- Topics: procedural-macro, rust-lang, utility
- Language: Rust
- Homepage:
- Size: 38.1 KB
- Stars: 1
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE-APACHE
Awesome Lists containing this project
README
# Automation of Destructure Pattern
[](https://crates.io/crates/destructure)
[](https://docs.rs/destructure/0.4.3/destructure/)`destructure` is an automation library for `destructure pattern`.
### What is `destructure pattern`?
A structure with too many fields makes it hard to call constructors, but it is also hard work to prepare a `Getter/Setter` for each one. There are macros for this purpose, but even so, a large number of macros reduces readability. This is especially true when using `From` Trait.So how can this be simplified? It is the technique of "converting all fields to public".
This allows for a simplified representation, as in the following example```rust
pub struct AuthenticateResponse {
id: Uuid,
user_code: String,
verification_uri: String,
expires_in: i32,
message: String,
// ... too many fields...
}impl AuthenticateResponse {
pub fn into_destruct(self) -> DestructAuthenticateResponse {
DestructAuthenticateResponse {
id: self.id,
user_code: self.user_code,
verification_uri: self.verification_uri,
expires_in: self.expires_in,
message: self.message,
// ...
}
}
}pub struct DestructAuthenticateResponse {
pub id: Uuid,
pub user_code: String,
pub verification_uri: String,
pub expires_in: i32,
pub message: String,
// ... too many fields (All `public`.)...
}#[tokio::main]
async fn main() {
let res = reqwest::get("http://example.com")
.send().await.unwrap()
.json::().await.unwrap();
let des = res.into_destruct();println!("{:?}", des.id);
}
```
There are several problems with this method, the most serious of which is the increase in boilerplate.
Using the multi-cursor feature of the editor, this can be done by copy-pasting, but it is still a hassle.Therefore, I created a *Procedural Macro* that automatically generates structures and methods:
```rust
use destructure::Destructure;#[derive(Destructure)]
pub struct AuthenticateResponse {
id: Uuid,
user_code: String,
verification_uri: String,
expires_in: i32,
message: String,
// ... too many fields...
}#[tokio::main]
async fn main() {
let res = reqwest::get("http://example.com")
.send().await.unwrap()
.json::().await.unwrap();// Auto generate
let des: DestructAuthenticateResponse = res.into_destruct();println!("{:?}", des.id);
}
```You can also perform safe value substitution by using `reconstruct()` or `substitute()`,
which performs the same role as the following usage.
```rust
use destructure::{Destructure, Mutation};#[derive(Destructure, Mutation)]
pub struct AuthenticateResponse {
id: Uuid,
user_code: String,
verification_uri: String,
expires_in: i32,
message: String,
// ... too many fields...
}#[tokio::main]
async fn main() {
let res = reqwest::get("http://example.com")
.send().await.unwrap()
.json::().await.unwrap();let message = "After".to_string();
// `reconstruct()` consumes self and provides the Destructed structure
// as a variable reference in a closure.
// Literally, it is a method that reconstructs.
let res: AuthenticateResponse = res.reconstruct(|before| {
before.message = message;
});
// substitute is a method that refills variable references of its own field values
// into another structure and provides them in a closure.
//
// This method is suitable for loop processing, etc.,
// because it processes by reference as opposed to reconstruct, which consumes values.
let mut res = res;
res.substitute(|before| {
*before.message = message;
});println!("{:?}", des.id);
}
```## Problem
It is still lacking in functionality, but we will accept PullRequests and Issues if there are any problems.