fog_pack/validator/
lockbox.rs

1use super::*;
2use crate::element::*;
3use crate::error::{Error, Result};
4use serde::{Deserialize, Serialize};
5
6#[inline]
7fn is_false(v: &bool) -> bool {
8    !v
9}
10
11#[inline]
12fn u32_is_zero(v: &u32) -> bool {
13    *v == 0
14}
15
16#[inline]
17fn u32_is_max(v: &u32) -> bool {
18    *v == u32::MAX
19}
20
21macro_rules! lockbox_validator {
22    ($t: ty, $e: ident, $v: ident, $link:expr, $name:expr) => {
23        #[doc = "Validator for a [`"]
24        #[doc = $name]
25        #[doc = "`]["]
26        #[doc = $link]
27        #[doc = "].\n\n"]
28        #[doc = "This validator will only pass a "]
29        #[doc = $name]
30        #[doc = " value. Validation passes if:\n\n"]
31        #[doc = "- The number of bytes in the lockbox is less than or equal to `max_len`\n"]
32        #[doc = "- The number of bytes in the lockbox is greater than or equal to `min_len`\n"]
33        /// # Defaults
34        ///
35        /// Fields that aren't specified for the validator use their defaults instead. The defaults for
36        /// each field are:
37        ///
38        /// - comment: ""
39        /// - max_len: u32::MAX
40        /// - min_len: 0
41        /// - size: false
42        ///
43        /// # Query Checking
44        ///
45        /// Queries for lockboxes are only allowed to use non default values for `max_len` and
46        /// `min_len` if `size` is set in the schema's validator.
47        ///
48        #[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
49        #[serde(deny_unknown_fields, default)]
50        pub struct $v {
51            /// An optional comment explaining the validator.
52            #[serde(skip_serializing_if = "String::is_empty")]
53            pub comment: String,
54            /// Set the maximum allowed number of bytes.
55            #[serde(skip_serializing_if = "u32_is_max")]
56            pub max_len: u32,
57            /// Set the minimum allowed number of bytes.
58            #[serde(skip_serializing_if = "u32_is_zero")]
59            pub min_len: u32,
60            /// If true, queries against matching spots may set the `min_len` and `max_len` values
61            /// to non-defaults.
62            #[serde(skip_serializing_if = "is_false")]
63            pub size: bool,
64        }
65
66        impl std::default::Default for $v {
67            fn default() -> Self {
68                Self {
69                    comment: String::new(),
70                    max_len: u32::MAX,
71                    min_len: u32::MIN,
72                    size: false,
73                }
74            }
75        }
76
77        impl $v {
78
79            /// Make a new validator with the default configuration.
80            pub fn new() -> Self {
81                Self::default()
82            }
83
84            /// Set a comment for the validator.
85            pub fn comment(mut self, comment: impl Into<String>) -> Self {
86                self.comment = comment.into();
87                self
88            }
89
90            /// Set the maximum number of allowed bytes.
91            pub fn max_len(mut self, max_len: u32) -> Self {
92                self.max_len = max_len;
93                self
94            }
95
96            /// Set the minimum number of allowed bytes.
97            pub fn min_len(mut self, min_len: u32) -> Self {
98                self.min_len = min_len;
99                self
100            }
101
102            /// Set whether or not queries can use the `max_len` and `min_len` values.
103            pub fn size(mut self, size: bool) -> Self {
104                self.size = size;
105                self
106            }
107
108            /// Build this into a [`Validator`] enum.
109            pub fn build(self) -> Validator {
110                Validator::$e(Box::new(self))
111            }
112
113            pub(crate) fn validate(&self, parser: &mut Parser) -> Result<()> {
114                let elem = parser
115                    .next()
116                    .ok_or_else(|| Error::FailValidate(concat!("Expected a ",$name).to_string()))??;
117                let elem = if let Element::$e(v) = elem {
118                    v
119                } else {
120                    return Err(Error::FailValidate(format!(
121                                concat!("Expected ", $name, ", got {}"),
122                                elem.name()
123                    )));
124                };
125
126                let len = elem.as_bytes().len() as u32;
127                if len > self.max_len {
128                    return Err(Error::FailValidate(
129                            concat!($name, " is longer than max_len").to_string()
130                    ));
131                }
132                if len < self.min_len {
133                    return Err(Error::FailValidate(
134                            concat!($name, " is shorter than min_len").to_string()
135                    ));
136                }
137
138                Ok(())
139            }
140
141            fn query_check_self(&self, other: &Self) -> bool {
142                self.size || (u32_is_max(&other.max_len) && u32_is_zero(&other.min_len))
143            }
144
145            pub(crate) fn query_check(&self, other: &Validator) -> bool {
146                match other {
147                    Validator::$e(other) => self.query_check_self(other),
148                    Validator::Multi(list) => list.iter().all(|other| match other {
149                        Validator::$e(other) => self.query_check_self(other),
150                        _ => false,
151                    }),
152                    Validator::Any => true,
153                    _ => false,
154                }
155            }
156        }
157    };
158
159    ($t: ty, $e: ident, $v: ident) => {
160        lockbox_validator!($t, $e, $v, concat!("fog_crypto::lockbox::", stringify!($t)), stringify!($t));
161    }
162}
163
164lockbox_validator!(DataLockbox, DataLockbox, DataLockboxValidator);
165lockbox_validator!(IdentityLockbox, IdentityLockbox, IdentityLockboxValidator);
166lockbox_validator!(StreamLockbox, StreamLockbox, StreamLockboxValidator);
167lockbox_validator!(LockLockbox, LockLockbox, LockLockboxValidator);