proto_types/protovalidate/
length_rules.rs

1use 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}