rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use super::char::validate_char_field;
use super::mixins::{FieldCacheMixin, FieldValidationMixin};
use crate::core::validators::validate_slug;

/// A SlugField stores URL-friendly strings.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SlugField {
    pub max_length: usize,
    pub allow_unicode: bool,
    pub db_index: bool,
}

impl Default for SlugField {
    fn default() -> Self {
        Self {
            max_length: 50,
            allow_unicode: false,
            db_index: true,
        }
    }
}

impl SlugField {
    #[must_use]
    pub fn new(max_length: usize) -> Self {
        Self {
            max_length,
            ..Self::default()
        }
    }

    #[must_use]
    pub fn with_unicode(mut self) -> Self {
        self.allow_unicode = true;
        self
    }

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

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

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

    fn is_cached(&self) -> bool {
        self.db_index
    }
}

impl FieldValidationMixin for SlugField {
    fn validate(&self, value: &str) -> Result<(), String> {
        validate_char_field(value, self.max_length).map_err(|error| error.message.clone())?;
        if self.allow_unicode {
            return Ok(());
        }

        validate_slug(value).map_err(|error| error.message)
    }
}

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

    #[test]
    fn slug_field_default_matches_django_defaults() {
        let field = SlugField::default();

        assert_eq!(field.max_length, 50);
        assert!(!field.allow_unicode);
        assert!(field.db_index);
    }

    #[test]
    fn slug_field_new_overrides_max_length() {
        let field = SlugField::new(128);

        assert_eq!(field.max_length, 128);
        assert!(field.db_index);
    }

    #[test]
    fn slug_field_with_unicode_enables_unicode_support() {
        let field = SlugField::default().with_unicode();

        assert!(field.allow_unicode);
    }

    #[test]
    fn slug_field_exposes_max_length() {
        let field = SlugField::new(64);

        assert_eq!(field.max_length(), 64);
    }

    #[test]
    fn slug_field_reports_varchar_db_type() {
        let field = SlugField::default();

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