use super::FieldType;
use super::integer::validate_integer_range;
use super::mixins::{FieldCacheMixin, FieldValidationMixin};
#[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)
}
}
#[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)
}
}
#[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");
}
}