Skip to main content

sift_query_core/query/
facet.rs

1use crate::{FieldId, FieldRef, RowValue, SearchEntity};
2
3/// A server-declared facet over one entity field.
4///
5/// The field is validated against the entity metadata before SQL is rendered;
6/// this type carries no client-provided SQL identifier or expression.
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct FacetRequest {
9    field: FieldId,
10    schema_fingerprint: u64,
11    limit: u32,
12    include_null: bool,
13    exclude_self_filter: bool,
14}
15
16impl FacetRequest {
17    #[must_use]
18    pub const fn new<E: SearchEntity, T, K>(field: FieldRef<E, T, K>, limit: u32) -> Self {
19        Self {
20            field: field.id(),
21            schema_fingerprint: E::META.schema_fingerprint,
22            limit,
23            include_null: true,
24            exclude_self_filter: false,
25        }
26    }
27
28    #[must_use]
29    pub const fn excluding_nulls(self) -> Self {
30        Self {
31            include_null: false,
32            ..self
33        }
34    }
35
36    /// Ignores user conditions on this field while computing this facet.
37    /// Server-owned scope predicates are always retained.
38    #[must_use]
39    pub const fn excluding_self_filter(self) -> Self {
40        Self {
41            exclude_self_filter: true,
42            ..self
43        }
44    }
45
46    #[must_use]
47    pub const fn field_id(self) -> FieldId {
48        self.field
49    }
50
51    #[must_use]
52    pub const fn schema_fingerprint(self) -> u64 {
53        self.schema_fingerprint
54    }
55
56    #[must_use]
57    pub const fn limit(self) -> u32 {
58        self.limit
59    }
60
61    #[must_use]
62    pub const fn includes_null(self) -> bool {
63        self.include_null
64    }
65
66    #[must_use]
67    pub const fn excludes_self_filter(self) -> bool {
68        self.exclude_self_filter
69    }
70}
71
72#[derive(Debug, Clone, PartialEq)]
73#[cfg_attr(feature = "serde", derive(serde::Serialize))]
74pub struct FacetBucket {
75    pub value: RowValue,
76    pub count: i64,
77}
78
79#[derive(Debug, Clone, PartialEq)]
80#[cfg_attr(feature = "serde", derive(serde::Serialize))]
81pub struct FacetResult {
82    pub field: &'static str,
83    pub buckets: Vec<FacetBucket>,
84    pub other_count: i64,
85}
86
87impl FacetResult {
88    #[must_use]
89    pub fn empty(field: &'static str) -> Self {
90        Self {
91            field,
92            buckets: Vec::new(),
93            other_count: 0,
94        }
95    }
96}