fieldmask/
lib.rs

1//! # fieldmask
2//! This is a Rust library that supports (de)serializing/applying field mask.
3//!
4//! ## Concepts
5//! - Atomic types: types that can only be used as a leaf node in a field mask. They can only be
6//!   included or excluded as a whole.
7//!
8//! ## Example
9//! ```rust
10//! use std::convert::TryFrom;
11//!
12//! use fieldmask::{Mask, MaskInput, Maskable, OptionMaskable, SelfMaskable};
13//!
14//! #[derive(Debug, Maskable, PartialEq, SelfMaskable)]
15//! struct Parent {
16//!     primitive: String,
17//!
18//!     child: Child,
19//!
20//!     // Child fields can be flattened into the parent.
21//!     #[fieldmask(flatten)]
22//!     flatten_child: Child,
23//!
24//!     one_of_field: Option<OneOfField>,
25//!
26//!     // You can use an enum to represent oneof fields from a protobuf message.
27//!     // Each variant in the enum must be tuple variant with a single inner type.
28//!     //
29//!     // If you flatten it, the behavior will be exactly the same as the protobuf message.
30//!     #[fieldmask(flatten)]
31//!     flatten_one_of_field: Option<OneOfField>,
32//!
33//!     // You can use an enum to enums from a protobuf message.
34//!     // Each variant in the enum must be a unit variant.
35//!     unit_enum: Option<UnitEnum>,
36//!     unit_enum_with_default: UnitEnumWithDefault,
37//! }
38//!
39//! #[derive(Debug, Default, Maskable, PartialEq, SelfMaskable)]
40//! struct Child {
41//!     field_one: String,
42//!     field_two: u32,
43//! }
44//!
45//! // You can derive `OptionMaskable` on tuple enums.
46//! // If you do so, `Option<MyTupleEnum>` will be `SelfMaskable`.
47//! #[derive(Debug, Maskable, OptionMaskable, PartialEq)]
48//! enum OneOfField {
49//!     VariantOne(String),
50//!     VariantTwo(u32),
51//! }
52//!
53//! // You can derive `OptionMaskable` on unit enums.
54//! // If you do so, `Option<UnitEnum>` will be `SelfMaskable`.
55//! #[derive(Debug, Maskable, OptionMaskable, PartialEq)]
56//! #[allow(dead_code)]
57//! enum UnitEnum {
58//!     One = 1,
59//!     Two = 2,
60//! }
61//!
62//! // If the unit enum implements `Default` and `PartialEq`, you can derive `SelfMaskable` for it.
63//! #[derive(Debug, Default, Maskable, PartialEq, SelfMaskable)]
64//! enum UnitEnumWithDefault {
65//!     #[default]
66//!     One = 1,
67//!     Two = 2,
68//! }
69//!
70//! mod project {
71//!     use super::*;
72//!
73//!     #[test]
74//!     fn case_1() {
75//!         let source = Parent {
76//!             primitive: "string".into(),
77//!
78//!             child: Child {
79//!                 field_one: "child field one".into(),
80//!                 field_two: 1,
81//!             },
82//!             flatten_child: Child {
83//!                 field_one: "flatten child field one".into(),
84//!                 field_two: 2,
85//!             },
86//!
87//!             one_of_field: Some(OneOfField::VariantOne("variant one".into())),
88//!             flatten_one_of_field: Some(OneOfField::VariantTwo(3)),
89//!
90//!             unit_enum: Some(UnitEnum::Two),
91//!             unit_enum_with_default: UnitEnumWithDefault::Two,
92//!         };
93//!         let mask = vec![
94//!             "primitive",
95//!             "child.field_two",
96//!             "field_one",
97//!             "one_of_field.variant_one",
98//!             "variant_two",
99//!             "unit_enum",
100//!             "unit_enum_with_default",
101//!         ];
102//!         let expected = Parent {
103//!             primitive: "string".into(),
104//!
105//!             child: Child {
106//!                 field_one: Default::default(),
107//!                 field_two: 1,
108//!             },
109//!             flatten_child: Child {
110//!                 field_one: "flatten child field one".into(),
111//!                 field_two: Default::default(),
112//!             },
113//!
114//!             one_of_field: Some(OneOfField::VariantOne("variant one".into())),
115//!             flatten_one_of_field: Some(OneOfField::VariantTwo(3)),
116//!
117//!             unit_enum: Some(UnitEnum::Two),
118//!             unit_enum_with_default: UnitEnumWithDefault::Two,
119//!         };
120//!
121//!         let actual = Mask::<Parent>::try_from(MaskInput(mask.into_iter()))
122//!             .expect("unable to deserialize mask")
123//!             .project(source);
124//!
125//!         assert_eq!(actual, expected);
126//!     }
127//! }
128//! ```
129
130// Make macros from fieldmask_derive available in this crate.
131// Without this, `::fieldmask::*` generated by fieldmask_derive will not work.
132extern crate self as fieldmask;
133
134mod mask;
135mod maskable;
136
137pub use fieldmask_derive::{Maskable, OptionMaskable, SelfMaskable, maskable_atomic};
138
139pub use mask::{Mask, MaskInput};
140pub use maskable::{
141    DeserializeMaskError, Maskable, OptionMaskable, ProjectOptions, SelfMaskable, UpdateOptions,
142};