Skip to main content

nautilus_core/
args.rs

1//! Structured argument types for query operations.
2
3use std::collections::HashMap;
4
5use crate::{Expr, OrderBy, Value};
6
7/// Arguments for eagerly loading a single relation in a query.
8///
9/// ```text
10/// include: { posts: { where: { published: true } } }
11/// ```
12#[derive(Debug, Default, Clone)]
13pub struct IncludeRelation {
14    /// Optional filter to apply to the included child records.
15    pub where_: Option<Expr>,
16}
17
18impl IncludeRelation {
19    /// Create a plain include with no child filter.
20    pub fn plain() -> Self {
21        IncludeRelation { where_: None }
22    }
23
24    /// Create an include with a child filter.
25    pub fn with_filter(filter: Expr) -> Self {
26        IncludeRelation {
27            where_: Some(filter),
28        }
29    }
30}
31
32/// Arguments accepted by `find_unique` and `find_unique_or_throw` delegate methods.
33///
34/// Uses a required `where_` filter (no ordering/pagination — implicit LIMIT 1).
35///
36/// # Example
37/// ```rust,ignore
38/// let args = FindUniqueArgs::new(
39///     User::columns().email.eq("alice@example.com"),
40/// );
41/// let user = client.user.find_unique(args).await?;
42/// ```
43#[derive(Debug, Clone)]
44pub struct FindUniqueArgs {
45    /// WHERE filter expression (required — must reference a unique/PK field).
46    pub where_: Expr,
47    /// Projection: only return the specified fields.
48    ///
49    /// If empty, all columns are returned. When specified, PK columns are
50    /// always included regardless. Cannot be used together with `include`.
51    pub select: HashMap<String, bool>,
52}
53
54impl FindUniqueArgs {
55    /// Construct with a required filter expression.
56    pub fn new(filter: Expr) -> Self {
57        FindUniqueArgs {
58            where_: filter,
59            select: HashMap::new(),
60        }
61    }
62}
63
64/// Arguments accepted by `find_many` and `find_first` delegate methods.
65///
66/// All fields are optional and default to "no constraint".
67///
68/// # Example
69/// ```rust,ignore
70/// let args = FindManyArgs {
71///     where_: Some(User::columns().email.eq("alice@example.com")),
72///     take: Some(10),
73///     ..Default::default()
74/// };
75/// let users = client.user.find_many(args).await?;
76/// ```
77#[derive(Debug, Default, Clone)]
78pub struct FindManyArgs {
79    /// Optional WHERE filter expression.
80    pub where_: Option<Expr>,
81    /// ORDER BY clauses (applied in order).
82    pub order_by: Vec<OrderBy>,
83    /// Maximum number of rows to return (LIMIT).
84    ///
85    /// Positive values paginate **forward**; negative values paginate
86    /// **backward** (reverses the result set in application code after
87    /// flipping `ORDER BY` directions — no DB-specific SQL needed).
88    /// Only meaningful when `cursor` is also set.
89    pub take: Option<i32>,
90    /// Number of rows to skip (OFFSET), applied relative to the cursor position
91    /// when `cursor` is set, or from the start of the result set otherwise.
92    pub skip: Option<u32>,
93    /// Relations to eager-load, with optional per-relation filters.
94    ///
95    /// Key is the relation field name (e.g. `"posts"`), value controls
96    /// how that relation is included (filter, etc.).
97    ///
98    /// Cannot be used together with `select`.
99    pub include: HashMap<String, IncludeRelation>,
100    /// Projection: only return the specified scalar fields.
101    ///
102    /// Key is the field name (logical name), value must be `true` to include
103    /// the field. PK fields are always returned regardless. When empty, all
104    /// columns are returned.
105    ///
106    /// Cannot be used together with `include`.
107    pub select: HashMap<String, bool>,
108    /// Cursor for stable (keyset) pagination.
109    ///
110    /// A map of **primary-key field name → value** that identifies the record
111    /// from which the page should start.  When
112    /// combined with `take` / `skip`, they are applied relative to this anchor
113    /// record rather than from the absolute start of the table.
114    ///
115    /// All primary-key fields of the model must be present in the map.
116    pub cursor: Option<HashMap<String, Value>>,
117    /// Columns to deduplicate on (SELECT DISTINCT / DISTINCT ON).
118    ///
119    /// Specifying one or more field names activates column-level deduplication:
120    /// - **Postgres**: rendered as `SELECT DISTINCT ON (col, ...)` with those
121    ///   columns automatically prepended to `ORDER BY` as required by Postgres.
122    /// - **SQLite / MySQL**: rendered as plain `SELECT DISTINCT` (full-row
123    ///   deduplication — most effective when combined with `select` projection).
124    ///
125    /// When empty (the default), no deduplication is applied.
126    pub distinct: Vec<String>,
127}