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"])
));
}
}