Skip to main content

flusso_query/handles/
object.rs

1//! Sub-document and opaque field handles: the flattened [`Object`], and the
2//! non-searchable [`Binary`] / [`Json`] fields (existence, or a raw clause).
3
4use std::marker::PhantomData;
5
6use serde_json::Value;
7
8use super::exists_q;
9use crate::query::{Query, Root};
10
11/// An `object` sub-document — a `group` or a to-one (`belongs_to`/`has_one`) join. Objects are
12/// **flattened**, so their sub-fields are queried by their own scope-`S`
13/// dotted-path handles directly (`Account::tier()`); this handle is for the
14/// object itself. `S` is the enclosing scope (`Root` at the top level).
15#[derive(Debug, Clone)]
16pub struct Object<S = Root> {
17    path: String,
18    _scope: PhantomData<fn() -> S>,
19}
20
21impl<S> Object<S> {
22    pub fn at(path: impl Into<String>) -> Self {
23        Self {
24            path: path.into(),
25            _scope: PhantomData,
26        }
27    }
28
29    /// The object is present — most useful on a nullable to-one join.
30    pub fn exists(&self) -> Query<S> {
31        exists_q(&self.path)
32    }
33}
34
35/// A `binary` field — base64-encoded, not searchable. Only existence.
36#[derive(Debug, Clone)]
37pub struct Binary<S = Root> {
38    path: String,
39    _scope: PhantomData<fn() -> S>,
40}
41
42impl<S> Binary<S> {
43    pub fn at(path: impl Into<String>) -> Self {
44        Self {
45            path: path.into(),
46            _scope: PhantomData,
47        }
48    }
49
50    /// The field has a non-null value.
51    pub fn exists(&self) -> Query<S> {
52        exists_q(&self.path)
53    }
54}
55
56/// An untyped `object`/`json` field. The escape hatch: existence, or a raw
57/// clause spliced in verbatim.
58#[derive(Debug, Clone)]
59pub struct Json<S = Root> {
60    path: String,
61    _scope: PhantomData<fn() -> S>,
62}
63
64impl<S> Json<S> {
65    pub fn at(path: impl Into<String>) -> Self {
66        Self {
67            path: path.into(),
68            _scope: PhantomData,
69        }
70    }
71
72    /// The field has a non-null value.
73    pub fn exists(&self) -> Query<S> {
74        exists_q(&self.path)
75    }
76
77    /// Splice a raw OpenSearch query clause in verbatim.
78    pub fn raw(&self, clause: Value) -> Query<S> {
79        Query::leaf(clause)
80    }
81}