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