rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use crate::core::validators::{URLValidator, Validator};

use super::mixins::{FieldCacheMixin, FieldValidationMixin};

/// A URLField stores validated URLs.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct URLField {
    pub max_length: usize,
}

impl Default for URLField {
    fn default() -> Self {
        Self { max_length: 200 }
    }
}

impl URLField {
    #[must_use]
    pub fn new(max_length: usize) -> Self {
        Self { max_length }
    }

    #[must_use]
    pub fn max_length(&self) -> usize {
        self.max_length
    }

    #[must_use]
    pub fn db_type(&self) -> &str {
        "VARCHAR"
    }
}

impl FieldCacheMixin for URLField {
    fn get_cache_name(&self) -> String {
        "url_field".to_string()
    }

    fn is_cached(&self) -> bool {
        false
    }
}

impl FieldValidationMixin for URLField {
    fn validate(&self, value: &str) -> Result<(), String> {
        if value.chars().count() > self.max_length {
            return Err(format!(
                "Ensure this value has at most {} characters.",
                self.max_length
            ));
        }

        URLValidator::default()
            .validate(&value)
            .map_err(|error| error.message)
    }
}

#[cfg(test)]
mod tests {
    use super::URLField;

    #[test]
    fn url_field_default_max_length_is_200() {
        let field = URLField::default();

        assert_eq!(field.max_length, 200);
    }

    #[test]
    fn url_field_reports_varchar_db_type() {
        let field = URLField::new(500);

        assert_eq!(field.max_length(), 500);
        assert_eq!(field.db_type(), "VARCHAR");
    }
}