Crates.io | relax |
lib.rs | relax |
version | 0.1.1 |
source | src |
created_at | 2024-07-15 10:00:45.517136 |
updated_at | 2024-11-07 21:33:42.775603 |
description | Derive Partial |
homepage | |
repository | https://codeberg.org/supnas/relax |
max_upload_size | |
id | 1303650 |
size | 13,583 |
Derive partial (“relaxed”) types
use relax::Relax;
#[derive(Relax)]
#[relax(PartialData)]
pub(crate) struct Data {
id: u16,
pub name: String,
pub favorite: Option<String>,
}
yields the following partial (“relaxed”) struct:
pub(crate) struct PartialData {
id: Option<u16>,
pub name: Option<String>,
pub favorite: Option<String>,
}
Nesting is also supported:
use relax::Relax;
#[derive(Relax)]
#[relax(PartialFoo)]
struct Foo {
id: u16,
#[relax]
bar: Bar,
#[relax]
bar2: Option<Bar>,
}
#[derive(Relax)]
#[relax(PartialBar)]
struct Bar {
name: String,
favorite: Option<String>,
}
yields
struct PatrialFoo {
id: Option<u16>,
bar: Option<PartialBar>,
bar2: Option<PartialBar>,
}
struct PartialBar {
name: Option<String>,
favorite: Option<String>,
}
You can also add attributes to generated structs:
use relax::Relax;
use serde::{Serialize, Deserialize};
#[derive(Relax)]
#[relax(PartialData, derive(Serialize, Deserialize), serde(rename_all = "UPPERCASE"))]
pub(crate) struct Data {
id: u16,
pub name: String,
pub favorite: Option<String>,
}
yields
#[derive(Serialize, Deserialize)]
#[serde(rename_all = "UPPERCASE")]
pub(crate) struct PartialData {
id: Option<u16>,
pub name: Option<String>,
pub favorite: Option<String>,
}
Relaxed structs derive Relaxed
trait, which has new
associated function.
use relax::{Relax, Relaxed};
#[derive(Relax)]
#[relax(PartialData, derive(Debug, PartialEq))]
pub(crate) struct Data {
id: u16,
pub name: String,
pub favorite: Option<String>,
}
let empty = PartialData {
id: None,
name: None,
favorite: None,
};
assert_eq!(PartialData::new(), empty);
Relaxed
trait also has merge
function. The behavior is similar to Option::or
, except that this function is applied for each struct field.
use relax::{Relax, Relaxed};
#[derive(Relax)]
#[relax(PartialData, derive(Debug, PartialEq))]
pub(crate) struct Data {
id: u16,
pub name: String,
pub favorite: Option<String>,
}
let partial_data_1 = PartialData {
id: None,
name: Some("John".to_owned()),
favorite: None,
};
let partial_data_2 = PartialData {
id: None,
name: None,
favorite: Some("Rust".to_owned()),
};
let merged = partial_data_1.merge(partial_data_2);
let expected = PartialData {
id: None,
name: Some("John".to_owned()),
favorite: Some("Rust".to_owned()),
};
assert_eq!(merged, expected);
If all the required fields of the original struct are set in a relaxed struct instance, you can use try_into()
to convert it to the original struct.
use relax::{Relax, Relaxed};
let partial_data_1: PartialData = read_data(file_1);
let partial_data_2: PartialData = read_data(file_2);
let partial_data_3: PartialData = read_data(file_3);
let data: Data = partial_data_1
.merge(partial_data_2)
.merge(partial_data_3)
.try_into()?;