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