avocado_schema/core/field/
array.rs1use crate::core::constraint::array::unique::Unique;
2use crate::core::constraint::common::typed::Type;
3use crate::core::constraint::Constraint;
4use crate::core::field::FieldEnum;
5use crate::core::field::{Field, FieldType};
6use serde::{Deserialize, Serialize};
7
8#[derive(Debug, Serialize, Deserialize)]
9#[serde(tag = "type", rename = "array")]
10pub struct ArrayField {
11 pub name: String,
12 pub item: Option<Box<FieldEnum>>,
13 pub unique: Option<bool>,
14}
15
16impl Field for ArrayField {
17 const FIELD_TYPE: FieldType = FieldType::Array;
18
19 fn name(&self) -> String {
20 self.name.clone()
21 }
22
23 fn constrains(&self) -> Vec<Box<dyn Constraint>> {
24 let mut constraints: Vec<Box<dyn Constraint>> = vec![Box::new(Type {
25 typed: Self::FIELD_TYPE,
26 })];
27 if let Some(c) = self.unique {
28 constraints.push(Box::new(Unique { unique: c }));
29 }
30 constraints
31 }
32}
33
34#[derive(Default)]
35pub struct ArrayFieldBuilder {
36 name: String,
37 item: Option<FieldEnum>,
38 unique: Option<bool>,
39}
40
41impl ArrayFieldBuilder {
42 pub fn new() -> ArrayFieldBuilder {
43 ArrayFieldBuilder::default()
44 }
45
46 pub fn name(mut self, name: &'static str) -> Self {
47 self.name = name.to_string();
48 self
49 }
50
51 pub fn item(mut self, item: impl Field) -> Self {
52 self.item = Some(item.into());
53 self
54 }
55
56 pub fn unique(mut self, unique: bool) -> Self {
57 self.unique = Some(unique);
58 self
59 }
60
61 pub fn build(self) -> ArrayField {
62 ArrayField {
63 name: self.name,
64 item: self.item.map(Box::new),
65 unique: self.unique,
66 }
67 }
68}
69
70#[cfg(test)]
71mod tests {
72 use crate::core::field::array::{ArrayField, ArrayFieldBuilder};
73 use crate::core::field::string::StringFieldBuilder;
74 use crate::core::field::FieldEnum;
75 use crate::visitor::validator::Validator;
76
77 #[test]
78 fn test_serialize() {
79 let field = ArrayFieldBuilder::new()
80 .name("tags")
81 .item(StringFieldBuilder::new().build())
82 .unique(true)
83 .build();
84 let field_json = serde_json::to_string(&field).unwrap();
85 assert_eq!(
86 field_json,
87 r#"{"type":"array","name":"tags","item":{"type":"string","name":""},"unique":true}"#
88 );
89 }
90
91 #[test]
92 fn test_deserialize() {
93 let field_json = r#"
94 {
95 "type":"array",
96 "name": "tags",
97 "item": {
98 "type":"string",
99 "name":"tag"
100 },
101 "unique": true
102 }"#;
103 let field: ArrayField = serde_json::from_str(field_json).unwrap();
104 assert!(matches!(*field.item.unwrap(), FieldEnum::String(_)));
105 assert!(field.unique.unwrap());
106 }
107
108 #[test]
109 fn test_type() {
110 let field = ArrayFieldBuilder::new().build();
111 let validator = Validator::new(field);
112
113 assert!(validator.validate(&vec![10, 20]).is_ok());
114 assert!(validator.validate(&"meeting").is_err());
115 }
116
117 #[test]
118 fn test_item() {
119 let field = ArrayFieldBuilder::new()
120 .item(StringFieldBuilder::new().build())
121 .build();
122 let validator = Validator::new(field);
123
124 assert!(validator.validate(&vec!["meeting", "email"]).is_ok());
125 assert!(validator.validate(&vec![1, 2]).is_err());
126 }
127
128 #[test]
129 fn test_unique() {
130 let field = ArrayFieldBuilder::new().unique(true).build();
131 let validator = Validator::new(field);
132
133 assert!(validator.validate(&vec![1, 2, 3]).is_ok());
134 assert!(validator.validate(&vec![1, 2, 2]).is_err());
135 }
136}