use super::FieldType;
use super::integer::validate_integer_range;
use super::mixins::{FieldCacheMixin, FieldValidationMixin};
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct PositiveIntegerField {
pub min_value: i64,
}
impl PositiveIntegerField {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn min_value(&self) -> i64 {
self.min_value
}
#[must_use]
pub fn db_type(&self) -> &str {
"INTEGER"
}
}
impl FieldCacheMixin for PositiveIntegerField {
fn get_cache_name(&self) -> String {
"positive_integer_field".to_string()
}
fn is_cached(&self) -> bool {
false
}
}
impl FieldValidationMixin for PositiveIntegerField {
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::PositiveInteger).map_err(|error| error.message)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct PositiveBigIntegerField {
pub min_value: i64,
}
impl PositiveBigIntegerField {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn min_value(&self) -> i64 {
self.min_value
}
#[must_use]
pub fn db_type(&self) -> &str {
"BIGINT"
}
}
impl FieldCacheMixin for PositiveBigIntegerField {
fn get_cache_name(&self) -> String {
"positive_big_integer_field".to_string()
}
fn is_cached(&self) -> bool {
false
}
}
impl FieldValidationMixin for PositiveBigIntegerField {
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::PositiveBigInteger)
.map_err(|error| error.message)
}
}
#[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct PositiveSmallIntegerField {
pub min_value: i64,
}
impl PositiveSmallIntegerField {
#[must_use]
pub fn new() -> Self {
Self::default()
}
#[must_use]
pub fn min_value(&self) -> i64 {
self.min_value
}
#[must_use]
pub fn db_type(&self) -> &str {
"SMALLINT"
}
}
impl FieldCacheMixin for PositiveSmallIntegerField {
fn get_cache_name(&self) -> String {
"positive_small_integer_field".to_string()
}
fn is_cached(&self) -> bool {
false
}
}
impl FieldValidationMixin for PositiveSmallIntegerField {
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::PositiveSmallInteger)
.map_err(|error| error.message)
}
}
#[cfg(test)]
mod tests {
use super::{PositiveBigIntegerField, PositiveIntegerField, PositiveSmallIntegerField};
#[test]
fn positive_integer_field_defaults_to_zero_minimum() {
let field = PositiveIntegerField::default();
assert_eq!(field.min_value(), 0);
assert_eq!(field.db_type(), "INTEGER");
}
#[test]
fn positive_big_and_small_integer_fields_use_non_negative_bounds() {
let big = PositiveBigIntegerField::default();
let small = PositiveSmallIntegerField::default();
assert_eq!(big.min_value(), 0);
assert_eq!(small.min_value(), 0);
assert_eq!(big.db_type(), "BIGINT");
assert_eq!(small.db_type(), "SMALLINT");
}
}