metabase_api_rs/repository/
factory.rs1use super::{
7 card::{CardRepository, HttpCardRepository, MockCardRepository},
8 collection::{CollectionRepository, HttpCollectionRepository, MockCollectionRepository},
9 dashboard::{DashboardRepository, HttpDashboardRepository, MockDashboardRepository},
10 query::{HttpQueryRepository, MockQueryRepository, QueryRepository},
11};
12use crate::transport::http_provider_safe::HttpProviderSafe;
13use std::sync::Arc;
14
15#[derive(Clone, Default)]
17pub struct RepositoryConfig {
18 pub use_mocks: bool,
20 pub http_provider: Option<Arc<dyn HttpProviderSafe>>,
22}
23
24impl std::fmt::Debug for RepositoryConfig {
25 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
26 f.debug_struct("RepositoryConfig")
27 .field("use_mocks", &self.use_mocks)
28 .field(
29 "http_provider",
30 &self.http_provider.as_ref().map(|_| "Arc<HttpProviderSafe>"),
31 )
32 .finish()
33 }
34}
35
36impl RepositoryConfig {
37 pub fn production(http_provider: Arc<dyn HttpProviderSafe>) -> Self {
39 Self {
40 use_mocks: false,
41 http_provider: Some(http_provider),
42 }
43 }
44
45 pub fn testing() -> Self {
47 Self {
48 use_mocks: true,
49 http_provider: None,
50 }
51 }
52}
53
54pub struct RepositoryFactory {
56 config: RepositoryConfig,
57}
58
59impl RepositoryFactory {
60 pub fn new(config: RepositoryConfig) -> Self {
62 Self { config }
63 }
64
65 pub fn create_card_repository(&self) -> Arc<dyn CardRepository> {
67 if self.config.use_mocks {
68 Arc::new(MockCardRepository::new())
69 } else {
70 let http_provider = self
71 .config
72 .http_provider
73 .as_ref()
74 .expect("HTTP provider required for non-mock repositories")
75 .clone();
76 Arc::new(HttpCardRepository::new(http_provider))
77 }
78 }
79
80 pub fn create_collection_repository(&self) -> Arc<dyn CollectionRepository> {
82 if self.config.use_mocks {
83 Arc::new(MockCollectionRepository::new())
84 } else {
85 let http_provider = self
86 .config
87 .http_provider
88 .as_ref()
89 .expect("HTTP provider required for non-mock repositories")
90 .clone();
91 Arc::new(HttpCollectionRepository::new(http_provider))
92 }
93 }
94
95 pub fn create_dashboard_repository(&self) -> Arc<dyn DashboardRepository> {
97 if self.config.use_mocks {
98 Arc::new(MockDashboardRepository::new())
99 } else {
100 let http_provider = self
101 .config
102 .http_provider
103 .as_ref()
104 .expect("HTTP provider required for non-mock repositories")
105 .clone();
106 Arc::new(HttpDashboardRepository::new(http_provider))
107 }
108 }
109
110 pub fn create_query_repository(&self) -> Arc<dyn QueryRepository> {
112 if self.config.use_mocks {
113 Arc::new(MockQueryRepository::new())
114 } else {
115 let http_provider = self
116 .config
117 .http_provider
118 .as_ref()
119 .expect("HTTP provider required for non-mock repositories")
120 .clone();
121 Arc::new(HttpQueryRepository::new(http_provider))
122 }
123 }
124
125 pub fn create_all(&self) -> RepositorySet {
127 RepositorySet {
128 card: self.create_card_repository(),
129 collection: self.create_collection_repository(),
130 dashboard: self.create_dashboard_repository(),
131 query: self.create_query_repository(),
132 }
133 }
134}
135
136pub struct RepositorySet {
138 pub card: Arc<dyn CardRepository>,
140 pub collection: Arc<dyn CollectionRepository>,
142 pub dashboard: Arc<dyn DashboardRepository>,
144 pub query: Arc<dyn QueryRepository>,
146}
147
148pub struct RepositoryFactoryBuilder {
150 use_mocks: bool,
151 http_provider: Option<Arc<dyn HttpProviderSafe>>,
152}
153
154impl Default for RepositoryFactoryBuilder {
155 fn default() -> Self {
156 Self::new()
157 }
158}
159
160impl RepositoryFactoryBuilder {
161 pub fn new() -> Self {
163 Self {
164 use_mocks: false,
165 http_provider: None,
166 }
167 }
168
169 pub fn with_mocks(mut self) -> Self {
171 self.use_mocks = true;
172 self
173 }
174
175 pub fn with_http_provider(mut self, provider: Arc<dyn HttpProviderSafe>) -> Self {
177 self.http_provider = Some(provider);
178 self.use_mocks = false;
179 self
180 }
181
182 pub fn build(self) -> RepositoryFactory {
184 let config = RepositoryConfig {
185 use_mocks: self.use_mocks,
186 http_provider: self.http_provider,
187 };
188 RepositoryFactory::new(config)
189 }
190}
191
192#[cfg(test)]
193mod tests {
194 use super::*;
195
196 #[test]
197 fn test_factory_with_mocks() {
198 let factory = RepositoryFactoryBuilder::new().with_mocks().build();
199
200 let repos = factory.create_all();
201
202 let _ = repos.card;
205 let _ = repos.collection;
206 let _ = repos.dashboard;
207 let _ = repos.query;
208 }
209
210 #[test]
211 fn test_config_presets() {
212 let test_config = RepositoryConfig::testing();
213 assert!(test_config.use_mocks);
214 assert!(test_config.http_provider.is_none());
215
216 }
219}