fog_pack/validator/
lock_id.rs

1use super::*;
2use crate::element::*;
3use crate::error::{Error, Result};
4use crate::LockId;
5use serde::{Deserialize, Serialize};
6
7#[inline]
8fn is_false(v: &bool) -> bool {
9    !v
10}
11
12/// Validator for a cryptographic [`LockId`][crate::LockId].
13///
14/// This validator will only pass a LockId value. Validation passes if:
15///
16/// - If the `in` list is not empty, the LockId must be among the ones in the list.
17/// - The LockId must not be among the ones in the `nin` list.
18///
19/// # Defaults
20///
21/// Fields that aren't specified for the validator use their defaults instead. The defaults for
22/// each field are:
23///
24/// - comment: ""
25/// - in_list: empty
26/// - nin_list: empty
27/// - query: false
28///
29#[derive(Clone, Debug, Default, PartialEq, Serialize, Deserialize)]
30#[serde(deny_unknown_fields, default)]
31pub struct LockIdValidator {
32    /// An optional comment explaining the validator.
33    #[serde(skip_serializing_if = "String::is_empty")]
34    pub comment: String,
35    /// A vector of specific allowed values, stored under the `in` field. If empty, this vector is not checked against.
36    #[serde(rename = "in", skip_serializing_if = "Vec::is_empty")]
37    pub in_list: Vec<LockId>,
38    /// A vector of specific unallowed values, stored under the `nin` field.
39    #[serde(rename = "nin", skip_serializing_if = "Vec::is_empty")]
40    pub nin_list: Vec<LockId>,
41    /// If true, queries against matching spots may have values in the `in` or `nin` lists.
42    #[serde(skip_serializing_if = "is_false")]
43    pub query: bool,
44}
45
46impl LockIdValidator {
47    /// Make a new validator with the default configuration.
48    pub fn new() -> Self {
49        Self::default()
50    }
51
52    /// Set a comment for the validator.
53    pub fn comment(mut self, comment: impl Into<String>) -> Self {
54        self.comment = comment.into();
55        self
56    }
57
58    /// Add a value to the `in` list.
59    pub fn in_add(mut self, add: impl Into<LockId>) -> Self {
60        self.in_list.push(add.into());
61        self
62    }
63
64    /// Add a value to the `nin` list.
65    pub fn nin_add(mut self, add: impl Into<LockId>) -> Self {
66        self.nin_list.push(add.into());
67        self
68    }
69
70    /// Set whether or not queries can use the `in` and `nin` lists.
71    pub fn query(mut self, query: bool) -> Self {
72        self.query = query;
73        self
74    }
75
76    /// Build this into a [`Validator`] enum.
77    pub fn build(self) -> Validator {
78        Validator::LockId(Box::new(self))
79    }
80
81    pub(crate) fn validate(&self, parser: &mut Parser) -> Result<()> {
82        let elem = parser
83            .next()
84            .ok_or_else(|| Error::FailValidate("Expected a LockId".to_string()))??;
85        let elem = if let Element::LockId(v) = elem {
86            v
87        } else {
88            return Err(Error::FailValidate(format!(
89                "Expected LockId, got {}",
90                elem.name()
91            )));
92        };
93        if !self.in_list.is_empty() && !self.in_list.iter().any(|v| v == elem.as_ref()) {
94            return Err(Error::FailValidate(
95                "LockId is not on `in` list".to_string(),
96            ));
97        }
98        if self.nin_list.iter().any(|v| v == elem.as_ref()) {
99            return Err(Error::FailValidate("LockId is on `nin` list".to_string()));
100        }
101        Ok(())
102    }
103
104    fn query_check_self(&self, other: &Self) -> bool {
105        self.query || (other.in_list.is_empty() && other.nin_list.is_empty())
106    }
107
108    pub(crate) fn query_check(&self, other: &Validator) -> bool {
109        match other {
110            Validator::LockId(other) => self.query_check_self(other),
111            Validator::Multi(list) => list.iter().all(|other| match other {
112                Validator::LockId(other) => self.query_check_self(other),
113                _ => false,
114            }),
115            Validator::Any => true,
116            _ => false,
117        }
118    }
119}