rjango 0.1.1

A full-stack Rust backend framework inspired by Django
Documentation
use sea_orm::Condition;

use crate::db::models::constants::LOOKUP_SEP;

#[derive(Debug, Clone)]
pub struct FilteredRelation {
    pub relation_name: String,
    pub condition: Option<Condition>,
}

#[derive(Debug, Clone, PartialEq, Eq)]
pub struct DeferredAttribute {
    pub field_name: String,
}

#[must_use]
pub fn select_related_descend(
    field_name: &str,
    restricted: bool,
    requested: Option<&[&str]>,
) -> bool {
    match requested {
        Some(fields) => fields.iter().any(|field| {
            *field == field_name
                || field
                    .strip_prefix(field_name)
                    .is_some_and(|suffix| suffix.starts_with(LOOKUP_SEP))
        }),
        None => !restricted,
    }
}

#[cfg(test)]
mod tests {
    use sea_orm::Condition;

    use super::{DeferredAttribute, FilteredRelation, select_related_descend};

    #[test]
    fn filtered_relation_stores_relation_name_and_condition() {
        let relation = FilteredRelation {
            relation_name: "author".to_string(),
            condition: Some(Condition::all()),
        };

        assert_eq!(relation.relation_name, "author");
        assert!(relation.condition.is_some());
    }

    #[test]
    fn deferred_attribute_stores_field_name() {
        let attribute = DeferredAttribute {
            field_name: "email".to_string(),
        };

        assert_eq!(attribute.field_name, "email");
    }

    #[test]
    fn select_related_descend_defaults_to_descending_when_unrestricted() {
        assert!(select_related_descend("author", false, None));
    }

    #[test]
    fn select_related_descend_stops_when_restricted_without_requests() {
        assert!(!select_related_descend("author", true, None));
    }

    #[test]
    fn select_related_descend_matches_exact_request() {
        assert!(select_related_descend("author", true, Some(&["author"])));
    }

    #[test]
    fn select_related_descend_matches_nested_request() {
        assert!(select_related_descend(
            "author",
            true,
            Some(&["author__profile"]),
        ));
    }

    #[test]
    fn select_related_descend_rejects_non_matching_request() {
        assert!(!select_related_descend(
            "author",
            false,
            Some(&["publisher"])
        ));
    }
}