Skip to main content

icydb/base/validator/
web.rs

1use crate::{design::prelude::*, traits::Validator};
2
3///
4/// MimeType
5///
6
7#[validator]
8pub struct MimeType;
9
10impl Validator<str> for MimeType {
11    fn validate(&self, s: &str, ctx: &mut dyn VisitorContext) {
12        let mut parts = s.split('/');
13
14        let type_part = parts.next();
15        let subtype_part = parts.next();
16
17        // Must contain exactly one '/'
18        if type_part.is_none() || subtype_part.is_none() || parts.next().is_some() {
19            ctx.issue(format!("MIME type '{s}' must contain exactly one '/'"));
20            return;
21        }
22
23        let is_valid_part = |part: &str| {
24            !part.is_empty()
25                && part
26                    .chars()
27                    .all(|c| c.is_ascii_alphanumeric() || "+.-".contains(c))
28        };
29
30        let type_part = type_part.unwrap();
31        let subtype_part = subtype_part.unwrap();
32
33        if !is_valid_part(type_part) || !is_valid_part(subtype_part) {
34            ctx.issue(format!(
35                "MIME type '{s}' contains invalid characters; \
36                 only alphanumeric, '+', '-', '.' allowed"
37            ));
38        }
39    }
40}
41
42///
43/// Url
44///
45
46#[validator]
47pub struct Url;
48
49impl Validator<str> for Url {
50    fn validate(&self, s: &str, ctx: &mut dyn VisitorContext) {
51        if !(s.starts_with("http://") || s.starts_with("https://")) {
52            ctx.issue(format!("URL '{s}' must start with 'http://' or 'https://'"));
53        }
54    }
55}