Skip to content

Commit

Permalink
feat: Implement patch for Box and Option (#31)
Browse files Browse the repository at this point in the history
  • Loading branch information
taorepoara authored Aug 12, 2024
1 parent a38c91e commit 0f1a765
Show file tree
Hide file tree
Showing 11 changed files with 334 additions and 8 deletions.
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");
}
2 changes: 1 addition & 1 deletion struct-patch/examples/patch-attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 0f1a765

Please sign in to comment.