rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use super::FieldType;
use super::integer::validate_integer_range;
use super::mixins::{FieldCacheMixin, FieldValidationMixin};

/// An AutoField stores an auto-incrementing 32-bit primary key.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct AutoField {
    pub primary_key: bool,
    pub editable: bool,
}

impl Default for AutoField {
    fn default() -> Self {
        Self {
            primary_key: true,
            editable: false,
        }
    }
}

impl AutoField {
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    #[must_use]
    pub fn primary_key(&self) -> bool {
        self.primary_key
    }

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

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

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

impl FieldValidationMixin for AutoField {
    fn validate(&self, value: &str) -> Result<(), String> {
        let parsed = value
            .parse::<i64>()
            .map_err(|_| "Enter a valid integer.".to_string())?;
        validate_integer_range(parsed, &FieldType::Auto).map_err(|error| error.message)
    }
}

/// A BigAutoField stores an auto-incrementing 64-bit primary key.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct BigAutoField {
    pub primary_key: bool,
    pub editable: bool,
}

impl Default for BigAutoField {
    fn default() -> Self {
        Self {
            primary_key: true,
            editable: false,
        }
    }
}

impl BigAutoField {
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    #[must_use]
    pub fn primary_key(&self) -> bool {
        self.primary_key
    }

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

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

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

impl FieldValidationMixin for BigAutoField {
    fn validate(&self, value: &str) -> Result<(), String> {
        let parsed = value
            .parse::<i64>()
            .map_err(|_| "Enter a valid integer.".to_string())?;
        validate_integer_range(parsed, &FieldType::BigAuto).map_err(|error| error.message)
    }
}

/// A SmallAutoField stores an auto-incrementing 16-bit primary key.
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct SmallAutoField {
    pub primary_key: bool,
    pub editable: bool,
}

impl Default for SmallAutoField {
    fn default() -> Self {
        Self {
            primary_key: true,
            editable: false,
        }
    }
}

impl SmallAutoField {
    #[must_use]
    pub fn new() -> Self {
        Self::default()
    }

    #[must_use]
    pub fn primary_key(&self) -> bool {
        self.primary_key
    }

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

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

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

impl FieldValidationMixin for SmallAutoField {
    fn validate(&self, value: &str) -> Result<(), String> {
        let parsed = value
            .parse::<i64>()
            .map_err(|_| "Enter a valid integer.".to_string())?;
        validate_integer_range(parsed, &FieldType::SmallAuto).map_err(|error| error.message)
    }
}

#[cfg(test)]
mod tests {
    use super::{AutoField, BigAutoField, SmallAutoField};

    #[test]
    fn auto_field_defaults_to_primary_key() {
        let field = AutoField::default();

        assert!(field.primary_key());
        assert_eq!(field.db_type(), "INTEGER");
    }

    #[test]
    fn big_and_small_auto_fields_default_to_primary_keys() {
        let big = BigAutoField::default();
        let small = SmallAutoField::default();

        assert!(big.primary_key());
        assert!(small.primary_key());
        assert_eq!(big.db_type(), "BIGINT");
        assert_eq!(small.db_type(), "SMALLINT");
    }
}