rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use serde_json::Value;

use crate::core::validators::ValidationError;

use super::FieldType;

pub fn parse_json_field(value: &str) -> Result<Value, ValidationError> {
    serde_json::from_str(value).map_err(|_| {
        ValidationError::new("Enter valid JSON.", "invalid").with_param("value", value)
    })
}

pub fn validate_json_field(_value: &Value) -> Result<(), ValidationError> {
    Ok(())
}

#[must_use]
pub fn db_type(field: &FieldType, vendor: &str) -> Option<String> {
    match field {
        FieldType::Json => Some(match vendor {
            "postgres" => "jsonb".to_string(),
            "mysql" => "json".to_string(),
            _ => "text".to_string(),
        }),
        _ => None,
    }
}

pub fn get_prep_value(value: &str) -> Result<String, ValidationError> {
    let parsed = parse_json_field(value)?;
    validate_json_field(&parsed)?;
    serde_json::to_string(&parsed).map_err(|_| {
        ValidationError::new("Enter valid JSON.", "invalid").with_param("value", value)
    })
}

pub fn from_db_value(value: &str) -> Result<Value, ValidationError> {
    parse_json_field(value)
}

#[must_use]
pub fn formfield(field: &FieldType) -> Option<&'static str> {
    match field {
        FieldType::Json => Some("JSONField"),
        _ => None,
    }
}

#[cfg(test)]
mod tests {
    use serde_json::json;

    use super::{FieldType, db_type, formfield, from_db_value, get_prep_value};

    #[test]
    fn db_type_for_postgres_uses_jsonb() {
        assert_eq!(
            db_type(&FieldType::Json, "postgres").as_deref(),
            Some("jsonb")
        );
    }

    #[test]
    fn get_prep_value_normalizes_json() {
        let prepared = get_prep_value("{\"a\":1, \"b\": true}")
            .expect("json preparation should serialize parsed values");
        assert_eq!(prepared, "{\"a\":1,\"b\":true}");
    }

    #[test]
    fn from_db_value_parses_json() {
        let parsed = from_db_value("{\"items\":[1,2]}").expect("database JSON should parse");
        assert_eq!(parsed, json!({"items": [1, 2]}));
    }

    #[test]
    fn formfield_returns_correct_type() {
        assert_eq!(formfield(&FieldType::Json), Some("JSONField"));
    }
}