prost_validate_types/
lib.rs

1#[allow(clippy::len_without_is_empty)]
2mod proto;
3
4use anyhow::anyhow;
5use once_cell::sync::Lazy;
6use prost_reflect::{
7    ExtensionDescriptor, FieldDescriptor, MessageDescriptor, OneofDescriptor, Value,
8};
9pub use proto::*;
10use std::borrow::Cow;
11
12#[allow(clippy::unwrap_used)]
13static VALIDATION_DISABLED: Lazy<ExtensionDescriptor> = Lazy::new(|| {
14    DESCRIPTOR_POOL
15        .get_extension_by_name("validate.disabled")
16        .ok_or(anyhow!("validate.disabled extension not found"))
17        .unwrap()
18});
19#[allow(clippy::unwrap_used)]
20static VALIDATION_IGNORED: Lazy<ExtensionDescriptor> = Lazy::new(|| {
21    DESCRIPTOR_POOL
22        .get_extension_by_name("validate.ignored")
23        .ok_or(anyhow!("validate.ignored extension not found"))
24        .unwrap()
25});
26#[allow(clippy::unwrap_used)]
27static VALIDATION_FIELD_RULES: Lazy<ExtensionDescriptor> = Lazy::new(|| {
28    DESCRIPTOR_POOL
29        .get_extension_by_name("validate.rules")
30        .ok_or(anyhow!("validate.rules extension not found"))
31        .unwrap()
32});
33#[allow(clippy::unwrap_used)]
34static VALIDATION_ONE_OF_RULES: Lazy<ExtensionDescriptor> = Lazy::new(|| {
35    DESCRIPTOR_POOL
36        .get_extension_by_name("validate.required")
37        .ok_or(anyhow!("validate.required extension not found"))
38        .unwrap()
39});
40
41pub trait FieldRulesExt {
42    fn validation_rules(&self) -> anyhow::Result<Option<FieldRules>>;
43}
44
45impl FieldRulesExt for FieldDescriptor {
46    fn validation_rules(&self) -> anyhow::Result<Option<FieldRules>> {
47        match self
48            .options()
49            .get_extension(&VALIDATION_FIELD_RULES)
50            .as_message()
51        {
52            Some(r) => Ok(Some(r.transcode_to::<FieldRules>()?)),
53            None => Ok(None),
54        }
55    }
56}
57
58pub trait OneofRulesExt {
59    fn required(&self) -> bool;
60}
61
62impl OneofRulesExt for OneofDescriptor {
63    fn required(&self) -> bool {
64        self.options()
65            .get_extension(&VALIDATION_ONE_OF_RULES)
66            .is_true()
67    }
68}
69
70pub trait MessageRulesExt {
71    fn validation_disabled(&self) -> bool;
72    fn validation_ignored(&self) -> bool;
73}
74
75impl MessageRulesExt for MessageDescriptor {
76    fn validation_disabled(&self) -> bool {
77        self.options().get_extension(&VALIDATION_DISABLED).is_true()
78    }
79
80    fn validation_ignored(&self) -> bool {
81        self.options().get_extension(&VALIDATION_IGNORED).is_true()
82    }
83}
84
85trait IsTrueExt {
86    fn is_true(&self) -> bool;
87}
88
89impl<'a> IsTrueExt for Cow<'a, Value> {
90    fn is_true(&self) -> bool {
91        self.as_bool().unwrap_or(false)
92    }
93}