proto_types/protovalidate/
length_rules.rs1use crate::protovalidate::{BytesRules, MapRules, RepeatedRules, StringRules};
2
3pub enum LengthRulesTarget {
4 String,
5 Bytes,
6 RepeatedItems,
7 MapPairs,
8}
9
10pub enum LengthRulesKind {
11 Len,
12 LenBytes,
13 RepeatedItems,
14 MapPairs,
15}
16
17pub struct LengthRules {
18 pub len: Option<u64>,
19 pub min_len: Option<u64>,
20 pub max_len: Option<u64>,
21 pub target: LengthRulesTarget,
22 pub kind: LengthRulesKind,
23}
24
25impl LengthRules {
26 pub fn name(&self) -> &'static str {
27 match self.target {
28 LengthRulesTarget::String => "string",
29 LengthRulesTarget::Bytes => "bytes",
30 LengthRulesTarget::RepeatedItems => "repeated",
31 LengthRulesTarget::MapPairs => "maps",
32 }
33 }
34
35 pub fn has_rule(&self) -> bool {
36 self.len.is_some() || self.min_len.is_some() || self.max_len.is_some()
37 }
38
39 pub fn unit(&self) -> &str {
40 match self.target {
41 LengthRulesTarget::String => "character",
42 LengthRulesTarget::Bytes => "byte",
43 LengthRulesTarget::RepeatedItems => "item",
44 LengthRulesTarget::MapPairs => "key-value pair",
45 }
46 }
47
48 pub fn len_name(&self) -> &str {
49 match self.kind {
50 LengthRulesKind::Len => "len",
51 LengthRulesKind::LenBytes => "len_bytes",
52 _ => "",
53 }
54 }
55
56 pub fn min_len_name(&self) -> &str {
57 match self.kind {
58 LengthRulesKind::Len => "min_len",
59 LengthRulesKind::LenBytes => "min_bytes",
60 LengthRulesKind::RepeatedItems => "min_items",
61 LengthRulesKind::MapPairs => "min_pairs",
62 }
63 }
64
65 pub fn max_len_name(&self) -> &str {
66 match self.kind {
67 LengthRulesKind::Len => "max_len",
68 LengthRulesKind::LenBytes => "max_bytes",
69 LengthRulesKind::RepeatedItems => "max_items",
70 LengthRulesKind::MapPairs => "max_pairs",
71 }
72 }
73
74 pub fn validate(self) -> Result<LengthRules, String> {
75 let len = self.len;
76 let min_len = self.min_len;
77 let max_len = self.max_len;
78
79 if len.is_some() && (min_len.is_some() || max_len.is_some()) {
80 return Err(format!(
81 "{} cannot be used with {} or {}",
82 self.len_name(),
83 self.min_len_name(),
84 self.max_len_name()
85 ));
86 }
87
88 if let Some(min) = min_len
89 && let Some(max) = max_len
90 && min > max {
91 return Err(format!("{} cannot be larger than {}", self.min_len_name(), self.max_len_name()));
92 }
93
94 Ok(self)
95 }
96}
97
98impl RepeatedRules {
99 pub fn length_rules(&self) -> Result<LengthRules, String> {
100 let min_len = self.min_items;
101 let max_len = self.max_items;
102
103 LengthRules {
104 len: None,
105 min_len,
106 max_len,
107 target: LengthRulesTarget::RepeatedItems,
108 kind: LengthRulesKind::RepeatedItems,
109 }
110 .validate()
111 }
112}
113
114impl MapRules {
115 pub fn length_rules(&self) -> Result<LengthRules, String> {
116 let min_len = self.min_pairs;
117 let max_len = self.max_pairs;
118
119 LengthRules {
120 len: None,
121 min_len,
122 max_len,
123 target: LengthRulesTarget::MapPairs,
124 kind: LengthRulesKind::MapPairs,
125 }
126 .validate()
127 }
128}
129
130impl BytesRules {
131 pub fn length_rules(&self) -> Result<LengthRules, String> {
132 let len = self.len;
133 let min_len = self.min_len;
134 let max_len = self.max_len;
135
136 LengthRules {
137 len,
138 min_len,
139 max_len,
140 target: LengthRulesTarget::Bytes,
141 kind: LengthRulesKind::Len,
142 }
143 .validate()
144 }
145}
146
147impl StringRules {
148 pub fn length_rules(&self) -> Result<LengthRules, String> {
149 let len = self.len;
150 let min_len = self.min_len;
151 let max_len = self.max_len;
152
153 LengthRules {
154 len,
155 min_len,
156 max_len,
157 target: LengthRulesTarget::String,
158 kind: LengthRulesKind::Len,
159 }
160 .validate()
161 }
162
163 pub fn bytes_length_rules(&self) -> Result<LengthRules, String> {
164 let len = self.len_bytes;
165 let min_len = self.min_bytes;
166 let max_len = self.max_bytes;
167
168 LengthRules {
169 len,
170 min_len,
171 max_len,
172 target: LengthRulesTarget::String,
173 kind: LengthRulesKind::LenBytes,
174 }
175 .validate()
176 }
177}