green_barrel/models/
validation.rs1use async_trait::async_trait;
4use mongodb::{
5 bson::{doc, oid::ObjectId, Bson, Document},
6 Collection,
7};
8use regex::{Regex, RegexBuilder};
9use serde_json::value::Value;
10use std::error::Error;
11
12#[async_trait(?Send)]
15pub trait Validation {
16 fn check_minlength(minlength: usize, value: &str) -> Result<(), Box<dyn Error>> {
19 if minlength > 0 && value.encode_utf16().count() < minlength {
20 Err(t!("min_chars", count = minlength))?
21 }
22 Ok(())
23 }
24
25 fn check_maxlength(maxlength: usize, value: &str) -> Result<(), Box<dyn Error>> {
28 if maxlength > 0 && value.encode_utf16().count() > maxlength {
29 Err(t!("max_chars", count = maxlength))?
30 }
31 Ok(())
32 }
33
34 fn accumula_err(field: &mut Value, err: &str) {
37 let err_vec = field["errors"].as_array_mut().unwrap();
38 let err = serde_json::to_value(err).unwrap();
39 if !err_vec.contains(&err) {
40 err_vec.push(err);
41 }
42 }
43
44 fn validation(field_type: &str, value: &str) -> Result<(), Box<dyn Error>> {
47 match field_type {
48 "EmailField" => {
49 if !validator::validate_email(value) {
50 Err(t!("invalid_email"))?
51 }
52 }
53 "URLField" => {
54 if !validator::validate_url(value) {
55 Err(t!("invalid_url"))?
56 }
57 }
58 "IPField" => {
59 if !validator::validate_ip(value) {
60 Err(t!("invalid_ip"))?
61 }
62 }
63 "IPv4Field" => {
64 if !validator::validate_ip_v4(value) {
65 Err(t!("invalid_ipv4"))?
66 }
67 }
68 "IPv6Field" => {
69 if !validator::validate_ip_v6(value) {
70 Err(t!("invalid_ipv6"))?
71 }
72 }
73 "ColorField" => {
74 if !(RegexBuilder::new(
75 r"^(?:#|0x)(?:[a-f0-9]{3}|[a-f0-9]{6}|[a-f0-9]{8})\b|(?:rgb|hsl)a?\([^\)]*\)$",
76 )
77 .case_insensitive(true)
78 .build()
79 .unwrap()
80 .is_match(value))
81 {
82 Err(t!("invalid_color"))?
83 }
84 }
85 _ => return Ok(()),
86 }
87 Ok(())
88 }
89
90 async fn check_unique(
93 hash: &str,
94 field_name: &str,
95 field_value_bson: &Bson,
96 coll: &Collection<Document>,
97 ) -> Result<(), Box<dyn Error>> {
98 let object_id = ObjectId::parse_str(hash);
100 let mut filter = doc! { field_name: field_value_bson };
101 if let Ok(id) = object_id {
102 filter = doc! {
104 "$and": [
105 { "_id": { "$ne": id } },
106 filter
107 ]
108 };
109 }
110 let count = coll.count_documents(filter, None).await?;
111 if count > 0 {
112 Err(t!("not_unique"))?
113 }
114 Ok(())
115 }
116
117 fn regex_validation(field_value: &str, regex_str: &str) -> Result<(), Box<dyn Error>> {
120 let pattern = Regex::new(regex_str)?;
121 if !field_value.is_empty() && !pattern.is_match(field_value) {
122 Err("")?
123 }
124 Ok(())
125 }
126}