Frederick Mayle | d6b6c53 | 2022-12-08 11:49:35 -0800 | [diff] [blame] | 1 | <!--- |
| 2 | Copyright (C) 2020 Robin Krahl <robin.krahl@ireas.org> |
| 3 | SPDX-License-Identifier: CC0-1.0 |
| 4 | --> |
| 5 | |
| 6 | # merge-rs |
| 7 | |
| 8 | The `merge` crate provides the `Merge` trait that can be used to merge multiple |
| 9 | values into one: |
| 10 | |
| 11 | ```rust |
| 12 | trait Merge { |
| 13 | fn merge(&mut self, other: Self); |
| 14 | } |
| 15 | ``` |
| 16 | |
| 17 | `Merge` is implemented for `Option` and can be derived for structs: |
| 18 | |
| 19 | <!-- should be kept in sync with examples/user.rs --> |
| 20 | ```rust |
| 21 | use merge::Merge; |
| 22 | |
| 23 | #[derive(Merge)] |
| 24 | struct User { |
| 25 | // Fields with the skip attribute are skipped by Merge |
| 26 | #[merge(skip)] |
| 27 | pub name: &'static str, |
| 28 | |
| 29 | // The Merge implementation for Option replaces its value if it is None |
| 30 | pub location: Option<&'static str>, |
| 31 | |
| 32 | // The strategy attribute is used to customize the merge behavior |
| 33 | #[merge(strategy = merge::vec::append)] |
| 34 | pub groups: Vec<&'static str>, |
| 35 | } |
| 36 | |
| 37 | let defaults = User { |
| 38 | name: "", |
| 39 | location: Some("Internet"), |
| 40 | groups: vec!["rust"], |
| 41 | }; |
| 42 | let mut ferris = User { |
| 43 | name: "Ferris", |
| 44 | location: None, |
| 45 | groups: vec!["mascot"], |
| 46 | }; |
| 47 | ferris.merge(defaults); |
| 48 | |
| 49 | assert_eq!("Ferris", ferris.name); |
| 50 | assert_eq!(Some("Internet"), ferris.location); |
| 51 | assert_eq!(vec!["mascot", "rust"], ferris.groups); |
| 52 | ``` |
| 53 | |
| 54 | A merge strategy is a function with the signature `fn merge<T>(left: &mut T, |
| 55 | right: T)` that merges `right` into `left`. The `merge` crate provides |
| 56 | strategies for the most common types, but you can also define your own |
| 57 | strategies. |
| 58 | |
| 59 | The trait can be used to merge configuration from different sources, for |
| 60 | example environment variables, multiple configuration files and command-line |
| 61 | arguments, see the `args.rs` example. |
| 62 | |
| 63 | ## Features |
| 64 | |
| 65 | This crate has the following features: |
| 66 | |
| 67 | - `derive` (default): Enables the derive macro for the `Merge` trait using the |
| 68 | `merge_derive` crate. |
| 69 | - `num` (default): Enables the merge strategies in the `num` module that |
| 70 | require the `num_traits` crate. |
| 71 | - `std` (default): Enables the merge strategies in the `vec` module that |
| 72 | require the standard library. If this feature is not set, `merge` is a |
| 73 | `no_std` library. |
| 74 | |
| 75 | ## Minimum Supported Rust Version |
| 76 | |
| 77 | This crate supports Rust 1.36.0 or later. |
| 78 | |
| 79 | ## Contact |
| 80 | |
| 81 | For bug reports, patches, feature requests and other messages, please send a |
| 82 | mail to [~ireas/public-inbox@lists.sr.ht][] using the `[merge-rs]` prefix in |
| 83 | the subject. |
| 84 | |
| 85 | ## License |
| 86 | |
| 87 | This project is dual-licensed under the [Apache-2.0][] and [MIT][] licenses. |
| 88 | The documentation and configuration files contained in this repository are |
| 89 | licensed under the [Creative Commons Zero][CC0] license. You can find a copy |
| 90 | of the license texts in the `LICENSES` directory. |
| 91 | |
| 92 | `merge-rs` complies with [version 3.0 of the REUSE specification][reuse]. |
| 93 | |
| 94 | [~ireas/public-inbox@lists.sr.ht]: mailto:~ireas/public-inbox@lists.sr.ht |
| 95 | [Apache-2.0]: https://opensource.org/licenses/Apache-2.0 |
| 96 | [MIT]: https://opensource.org/licenses/MIT |
| 97 | [CC0]: https://creativecommons.org/publicdomain/zero/1.0/ |
| 98 | [reuse]: https://reuse.software/practices/3.0/ |