use crate::db::{
contracts::first_violated_rule,
query::plan::{
LoadSpec, validate::FluentLoadPolicyViolation,
validate::cursor_policy::validate_cursor_paging_requirements,
},
};
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct FluentNonPagedPolicyContext {
has_cursor_token: bool,
has_grouping: bool,
}
impl FluentNonPagedPolicyContext {
#[must_use]
const fn new(has_cursor_token: bool, has_grouping: bool) -> Self {
Self {
has_cursor_token,
has_grouping,
}
}
}
type FluentNonPagedPolicyRule =
fn(FluentNonPagedPolicyContext) -> Option<FluentLoadPolicyViolation>;
const FLUENT_NON_PAGED_POLICY_RULES: &[FluentNonPagedPolicyRule] = &[
fluent_non_paged_cursor_token_violation,
fluent_non_paged_grouped_violation,
];
fn fluent_non_paged_cursor_token_violation(
ctx: FluentNonPagedPolicyContext,
) -> Option<FluentLoadPolicyViolation> {
(ctx.has_cursor_token && !ctx.has_grouping)
.then_some(FluentLoadPolicyViolation::cursor_requires_paged_execution())
}
const fn fluent_non_paged_grouped_violation(
ctx: FluentNonPagedPolicyContext,
) -> Option<FluentLoadPolicyViolation> {
let _ = ctx;
None
}
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
struct FluentPagedPolicyContext {
has_grouping: bool,
}
impl FluentPagedPolicyContext {
#[must_use]
const fn new(has_grouping: bool) -> Self {
Self { has_grouping }
}
}
type FluentPagedPolicyRule = fn(FluentPagedPolicyContext) -> Option<FluentLoadPolicyViolation>;
const FLUENT_PAGED_POLICY_RULES: &[FluentPagedPolicyRule] = &[fluent_paged_grouped_violation];
fn fluent_paged_grouped_violation(
ctx: FluentPagedPolicyContext,
) -> Option<FluentLoadPolicyViolation> {
ctx.has_grouping
.then_some(FluentLoadPolicyViolation::grouped_requires_direct_execute())
}
pub(crate) fn validate_fluent_non_paged_mode(
has_cursor_token: bool,
has_grouping: bool,
) -> Result<(), FluentLoadPolicyViolation> {
let context = FluentNonPagedPolicyContext::new(has_cursor_token, has_grouping);
first_violated_rule(FLUENT_NON_PAGED_POLICY_RULES, context).map_or(Ok(()), Err)
}
pub(crate) fn validate_fluent_paged_mode(
has_grouping: bool,
has_explicit_order: bool,
spec: Option<LoadSpec>,
) -> Result<(), FluentLoadPolicyViolation> {
let context = FluentPagedPolicyContext::new(has_grouping);
first_violated_rule(FLUENT_PAGED_POLICY_RULES, context)
.map_or(Ok(()), Err)
.and_then(|()| match spec {
Some(spec) => validate_cursor_paging_requirements(has_explicit_order, spec)
.map_err(FluentLoadPolicyViolation::from),
None => Ok(()),
})
}