Skip to main content

rustauth_core/db/adapter/
join.rs

1use indexmap::IndexMap;
2use serde::{Deserialize, Serialize};
3
4/// User-facing join request before schema relation metadata has been resolved.
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub struct JoinOption {
7    pub enabled: bool,
8    pub limit: Option<usize>,
9}
10
11impl JoinOption {
12    pub fn enabled() -> Self {
13        Self {
14            enabled: true,
15            limit: None,
16        }
17    }
18
19    pub fn disabled() -> Self {
20        Self {
21            enabled: false,
22            limit: None,
23        }
24    }
25
26    pub fn limit(mut self, limit: usize) -> Self {
27        self.limit = Some(limit);
28        self
29    }
30}
31
32/// Resolved join column pair.
33#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
34pub struct JoinOn {
35    pub from: String,
36    pub to: String,
37}
38
39impl JoinOn {
40    pub fn new(from: impl Into<String>, to: impl Into<String>) -> Self {
41        Self {
42            from: from.into(),
43            to: to.into(),
44        }
45    }
46}
47
48/// Resolved relation kind for joined output.
49#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
50pub enum JoinRelation {
51    OneToOne,
52    OneToMany,
53    ManyToMany,
54}
55
56/// Adapter-facing join configuration after relation metadata is resolved.
57#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
58pub struct JoinConfig {
59    pub on: JoinOn,
60    pub limit: Option<usize>,
61    pub relation: JoinRelation,
62}
63
64impl JoinConfig {
65    pub fn new(from: impl Into<String>, to: impl Into<String>) -> Self {
66        Self {
67            on: JoinOn::new(from, to),
68            limit: None,
69            relation: JoinRelation::OneToMany,
70        }
71    }
72
73    pub fn limit(mut self, limit: usize) -> Self {
74        self.limit = Some(limit);
75        self
76    }
77
78    pub fn relation(mut self, relation: JoinRelation) -> Self {
79        self.relation = relation;
80        self
81    }
82}
83
84/// Resolved join metadata plus any base select fields required to execute it.
85#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
86pub struct JoinResolution {
87    pub joins: IndexMap<String, JoinConfig>,
88    pub select: Vec<String>,
89}
90
91impl JoinResolution {
92    pub fn new(select: Vec<String>) -> Self {
93        Self {
94            joins: IndexMap::new(),
95            select,
96        }
97    }
98}