Skip to main content

sift_query_core/extensions/
mod.rs

1//! Bounded parameter normalization extension points.
2use crate::{EntityMeta, ParamError, QueryLimits, RawParams};
3use sift_query_algorithm::StableHasher64;
4use std::fmt;
5
6mod param_filters;
7
8// Keep declarations in this module: default fingerprints use their historical
9// Rust type paths. Only implementations move into the private child module.
10/// Converts repeated/indexed array keys to canonical indexed parameters.
11#[derive(Debug, Clone, Copy, Default)]
12pub struct IndexedArrayParamFilter;
13
14/// Expands JSON arrays into indexed parameter values before strict parsing.
15#[derive(Debug, Clone, Copy, Default)]
16pub struct JsonArrayParamFilter;
17
18/// Rewrites operator suffixes to canonical parameters while preserving repeats.
19#[derive(Debug, Clone, Copy, Default)]
20pub struct SuffixOperatorParamFilter;
21
22/// Adds trusted default parameters before strict parsing.
23#[derive(Debug, Clone, Default)]
24pub struct DefaultParamFilter {
25    entries: Vec<(String, String)>,
26}
27
28/// A server-owned parameter normalization step.
29pub trait RawParamFilter: Send + Sync + fmt::Debug {
30    /// Normalize `input` while preserving ordered, repeated parameters.
31    fn filter(
32        &self,
33        entity: &'static EntityMeta,
34        input: &RawParams,
35    ) -> Result<RawParams, ParamError>;
36
37    /// Budget-aware entry point. Server code must perform bounded synchronous
38    /// work; arbitrary extension code cannot be preempted safely by core.
39    fn filter_with_limits(
40        &self,
41        entity: &'static EntityMeta,
42        input: &RawParams,
43        _limits: &QueryLimits,
44    ) -> Result<RawParams, ParamError> {
45        self.filter(entity, input)
46    }
47
48    /// Stable identity used by query policy fingerprints.
49    fn fingerprint(&self) -> u64 {
50        let mut hash = StableHasher64::default();
51        hash.write_delimited(std::any::type_name::<Self>());
52        hash.finish()
53    }
54}