Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Implement patch for Box and Option #31

Merged
merged 1 commit into from
Aug 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,24 @@ jobs:
with:
github_access_token: ${{ secrets.GITHUB_TOKEN }}

- name: Test no defualt features
- name: Test no default features
run: |
nix develop -c cargo run --no-default-features --example instance
nix develop -c cargo run --no-default-features --example diff
nix develop -c cargo run --no-default-features --example json
nix develop -c cargo run --no-default-features --example rename-patch-struct
nix develop -c cargo run --no-default-features --example patch-attr
nix develop -c cargo test --no-default-features

- name: Test with std features
run: |
nix develop -c cargo run --features=std --example instance
nix develop -c cargo run --features=std --example diff
nix develop -c cargo run --features=std --example json
nix develop -c cargo run --features=std --example rename-patch-struct
nix develop -c cargo run --features=std --example patch-attr
nix develop -c cargo run --features=std --example option
nix develop -c cargo test --features=std

- name: Test with default features
run: |
Expand Down
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,15 @@ The [examples][examples] demo following scenarios.
- check a patch is empty or not
- add attribute to patch struct

## Features

This crate also includes the following optional features:
- `status`: implements the `PatchStatus` trait for the patch struct, which provides the `is_empty` method.
- `box`: implements the `Patch<Box<P>>` trait for `T` where `T` implements `Patch<P>`.
This let you patch a boxed (or not) struct with a boxed patch.
- `option`: implements the `Patch<Option<P>>` trait for `Option<T>` where `T` implements `Patch<P>`.
`T` also needs to implement `From<P>`.
This let you patch structs containing fields with optional values.

[crates-badge]: https://img.shields.io/crates/v/struct-patch.svg
[crate-url]: https://crates.io/crates/struct-patch
Expand Down
4 changes: 3 additions & 1 deletion struct-patch/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ serde_with = "3.9.0"

[features]
default = ["status"]
std = ["box", "option"]
box = []
option = []
status = [
"struct-patch-derive/status"
]

2 changes: 1 addition & 1 deletion struct-patch/examples/diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ fn main() {
};

// Diff on two items to get the patch
let patch = new_item.into_patch_by_diff(item);
let patch: ItemPatch = new_item.into_patch_by_diff(item);

assert_eq!(
format!("{patch:?}"),
Expand Down
2 changes: 1 addition & 1 deletion struct-patch/examples/instance.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ struct Item {
fn main() {
let mut item = Item::default();

let mut patch = Item::new_empty_patch();
let mut patch: ItemPatch = Item::new_empty_patch();

patch.field_int = Some(7);

Expand Down
57 changes: 57 additions & 0 deletions struct-patch/examples/option.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
#[cfg(feature = "option")]
use struct_patch::Patch;

#[cfg(feature = "option")]
fn main() {
#[derive(Default, Debug, PartialEq, Patch)]
#[patch(attribute(derive(Debug, Default)))]
struct User {
name: String,
#[patch(name = "Option<AddressPatch>")]
address: Option<Address>,
}

#[derive(Default, Debug, PartialEq, Patch)]
#[patch(attribute(derive(Debug, Default)))]
struct Address {
street: Option<String>,
country: String,
}

impl From<AddressPatch> for Address {
fn from(patch: AddressPatch) -> Self {
let mut address = Address::default();
address.apply(patch);
address
}
}

let mut user = User {
name: String::from("Thomas"),
address: None,
};
let mut patch: UserPatch = User::new_empty_patch();

patch.address = Some(Some(AddressPatch {
country: Some("France".to_string()),
..Default::default()
}));

user.apply(patch);

assert_eq!(
user,
User {
name: String::from("Thomas"),
address: Some(Address {
street: None,
country: String::from("France"),
}),
}
);
}

#[cfg(not(feature = "option"))]
fn main() {
println!("Please enable the 'option' feature to run this example");
}
4 changes: 2 additions & 2 deletions struct-patch/examples/patch-attr.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use struct_patch::Patch;
use serde_with::skip_serializing_none;
use struct_patch::Patch;

#[derive(Default, Patch)]
#[patch(attribute(derive(serde::Serialize, Debug, Default)))]
Expand All @@ -21,7 +21,7 @@ struct Item {
// }

fn main() {
let patch = Item::new_empty_patch();
let patch: ItemPatch = Item::new_empty_patch();

assert_eq!(
format!("{patch:?}"),
Expand Down
2 changes: 1 addition & 1 deletion struct-patch/examples/rename-patch-struct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ struct Item {
// }

fn main() {
let patch = Item::new_empty_patch();
let patch: ItemOverlay = Item::new_empty_patch();

assert_eq!(
format!("{patch:?}"),
Expand Down
2 changes: 1 addition & 1 deletion struct-patch/examples/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ struct Item {
}

fn main() {
let mut patch = Item::new_empty_patch();
let mut patch: ItemPatch = Item::new_empty_patch();

#[cfg(feature = "status")]
assert!(patch.is_empty()); // provided by PatchStatus
Expand Down
4 changes: 3 additions & 1 deletion struct-patch/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,12 @@
//! ```
//!
//! More details on how to use the the derive macro, including what attributes are available, are available under [`Patch`]
#![cfg_attr(not(test), no_std)]
#![cfg_attr(not(any(test, feature = "box", feature = "option")), no_std)]

#[doc(hidden)]
pub use struct_patch_derive::Patch;
#[cfg(any(feature = "box", feature = "option"))]
pub mod std;
pub mod traits;
pub use traits::*;

Expand Down
Loading