relax

Crates.iorelax
lib.rsrelax
version0.1.1
sourcesrc
created_at2024-07-15 10:00:45.517136
updated_at2024-11-07 21:33:42.775603
descriptionDerive Partial
homepage
repositoryhttps://codeberg.org/supnas/relax
max_upload_size
id1303650
size13,583
naskya (naskya)

documentation

README

relax

Derive partial (“relaxed”) types

Usage

Generate “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>,
}

Create empty “relaxed” instances

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);

Combine multiple “relaxed” instances

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);

Create an original struct instance from a relaxed instance

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()?;
Commit count: 0

cargo fmt