avocado_schema/core/field/
integer.rs1use crate::core::constraint::common::typed::Type;
2use crate::core::constraint::number::enumeration::Enumeration;
3use crate::core::constraint::number::exclusive_maximum::ExclusiveMaximum;
4use crate::core::constraint::number::exclusive_minimum::ExclusiveMinimum;
5use crate::core::constraint::number::maximum::Maximum;
6use crate::core::constraint::number::minimum::Minimum;
7use crate::core::constraint::Constraint;
8use crate::core::field::{Field, FieldType};
9use serde::{Deserialize, Serialize};
10
11#[derive(Debug, Serialize, Deserialize)]
12#[serde(tag = "type", rename = "integer")]
13pub struct IntegerField {
14 pub name: String,
15 #[serde(rename = "enum", skip_serializing_if = "Option::is_none")]
16 pub enumeration: Option<Vec<i64>>,
17 #[serde(skip_serializing_if = "Option::is_none")]
18 pub maximum: Option<i64>,
19 #[serde(rename = "exclusiveMaximum", skip_serializing_if = "Option::is_none")]
20 pub exclusive_maximum: Option<i64>,
21 #[serde(skip_serializing_if = "Option::is_none")]
22 pub minimum: Option<i64>,
23 #[serde(rename = "exclusiveMinimum", skip_serializing_if = "Option::is_none")]
24 pub exclusive_minimum: Option<i64>,
25}
26
27impl Field for IntegerField {
28 const FIELD_TYPE: FieldType = FieldType::Integer;
29
30 fn name(&self) -> String {
31 self.name.clone()
32 }
33
34 fn constrains(&self) -> Vec<Box<dyn Constraint>> {
35 let mut constraints: Vec<Box<dyn Constraint>> = vec![Box::new(Type {
36 typed: Self::FIELD_TYPE,
37 })];
38 if let Some(c) = &self.enumeration {
39 constraints.push(Box::new(Enumeration { values: c.clone() }))
40 }
41 if let Some(c) = &self.maximum {
42 constraints.push(Box::new(Maximum { max_val: *c }))
43 }
44 if let Some(c) = &self.exclusive_maximum {
45 constraints.push(Box::new(ExclusiveMaximum { max_val: *c }))
46 }
47 if let Some(c) = &self.minimum {
48 constraints.push(Box::new(Minimum { min_val: *c }))
49 }
50 if let Some(c) = &self.exclusive_minimum {
51 constraints.push(Box::new(ExclusiveMinimum { min_val: *c }))
52 }
53 constraints
54 }
55}
56
57#[derive(Default)]
58pub struct IntegerFieldBuilder {
59 name: String,
60 enumeration: Option<Vec<i64>>,
61 maximum: Option<i64>,
62 exclusive_maximum: Option<i64>,
63 minimum: Option<i64>,
64 exclusive_minimum: Option<i64>,
65}
66
67impl IntegerFieldBuilder {
68 pub fn new() -> Self {
69 IntegerFieldBuilder::default()
70 }
71
72 pub fn name(mut self, name: &'static str) -> Self {
73 self.name = name.to_string();
74 self
75 }
76
77 pub fn enumeration(mut self, numbers: Vec<i64>) -> Self {
78 self.enumeration = Some(numbers);
79 self
80 }
81
82 pub fn maximum(mut self, max: i64) -> Self {
83 self.maximum = Some(max);
84 self
85 }
86
87 pub fn exclusive_maximum(mut self, max: i64) -> Self {
88 self.exclusive_maximum = Some(max);
89 self
90 }
91
92 pub fn minimum(mut self, min: i64) -> Self {
93 self.minimum = Some(min);
94 self
95 }
96
97 pub fn exclusive_minimum(mut self, min: i64) -> Self {
98 self.exclusive_minimum = Some(min);
99 self
100 }
101
102 pub fn build(self) -> IntegerField {
103 IntegerField {
104 name: self.name,
105 enumeration: self.enumeration,
106 maximum: self.maximum,
107 exclusive_maximum: self.exclusive_maximum,
108 minimum: self.minimum,
109 exclusive_minimum: self.exclusive_minimum,
110 }
111 }
112}
113
114#[cfg(test)]
115mod tests {
116 use crate::core::field::integer::{IntegerField, IntegerFieldBuilder};
117 use crate::visitor::validator::Validator;
118
119 #[test]
120 fn test_serialize() {
121 let field = IntegerFieldBuilder::new()
122 .name("age")
123 .enumeration(vec![50, 100])
124 .maximum(100)
125 .exclusive_maximum(101)
126 .minimum(1)
127 .exclusive_minimum(0)
128 .build();
129 let field_json = serde_json::to_string(&field).unwrap();
130 assert_eq!(
131 field_json,
132 r#"{"type":"integer","name":"age","enum":[50,100],"maximum":100,"exclusiveMaximum":101,"minimum":1,"exclusiveMinimum":0}"#
133 );
134 }
135
136 #[test]
137 fn test_deserialize() {
138 let field_json = r#"
139 {
140 "type":"integer",
141 "name": "age",
142 "enum": [50, 100],
143 "maximum": 100,
144 "exclusiveMaximum": 101,
145 "minimum": 1,
146 "exclusiveMinimum": 0
147 }"#;
148 let field: IntegerField = serde_json::from_str(field_json).unwrap();
149 assert_eq!(field.name, "age");
150 assert_eq!(field.enumeration.unwrap(), vec![50, 100]);
151 assert_eq!(field.maximum.unwrap(), 100);
152 assert_eq!(field.exclusive_maximum.unwrap(), 101);
153 assert_eq!(field.minimum.unwrap(), 1);
154 assert_eq!(field.exclusive_minimum.unwrap(), 0);
155 }
156
157 #[test]
158 fn test_type() {
159 let field = IntegerFieldBuilder::new().build();
160 let validator = Validator::new(field);
161
162 assert!(validator.validate(&10).is_ok());
163 assert!(validator.validate(&"meeting").is_err());
164 }
165
166 #[test]
167 fn test_enumeration() {
168 let field = IntegerFieldBuilder::new()
169 .enumeration(vec![50, 100])
170 .build();
171 let validator = Validator::new(field);
172
173 assert!(validator.validate(&50).is_ok());
174 assert!(validator.validate(&30).is_err());
175 }
176
177 #[test]
178 fn test_maximum() {
179 let field = IntegerFieldBuilder::new().maximum(100).build();
180 let validator = Validator::new(field);
181
182 assert!(validator.validate(&99).is_ok());
183 assert!(validator.validate(&100).is_ok());
184 assert!(validator.validate(&101).is_err());
185 }
186
187 #[test]
188 fn test_exclusive_maximum() {
189 let field = IntegerFieldBuilder::new().exclusive_maximum(100).build();
190 let validator = Validator::new(field);
191
192 assert!(validator.validate(&99).is_ok());
193 assert!(validator.validate(&100).is_err());
194 assert!(validator.validate(&101).is_err());
195 }
196
197 #[test]
198 fn test_minimum() {
199 let field = IntegerFieldBuilder::new().minimum(1).build();
200 let validator = Validator::new(field);
201
202 assert!(validator.validate(&2).is_ok());
203 assert!(validator.validate(&1).is_ok());
204 assert!(validator.validate(&0).is_err())
205 }
206
207 #[test]
208 fn test_exclusive_minimum() {
209 let field = IntegerFieldBuilder::new().exclusive_minimum(1).build();
210 let validator = Validator::new(field);
211
212 assert!(validator.validate(&2).is_ok());
213 assert!(validator.validate(&1).is_err());
214 assert!(validator.validate(&0).is_err())
215 }
216}