1use crate::mgmtx::bucket_settings_json::BucketSettingsJson;
20use std::fmt::Display;
21use std::string::ToString;
22use std::time::Duration;
23use url::form_urlencoded::Serializer;
24
25#[derive(Default, Debug, Clone, PartialOrd, PartialEq, Eq)]
26pub struct BucketSettings {
27 pub flush_enabled: Option<bool>,
28 pub ram_quota_mb: Option<u64>,
29 pub replica_number: Option<u32>,
30 pub eviction_policy: Option<EvictionPolicyType>,
31 pub max_ttl: Option<Duration>,
32 pub compression_mode: Option<CompressionMode>,
33 pub durability_min_level: Option<DurabilityLevel>,
34 pub history_retention_collection_default: Option<bool>,
35 pub history_retention_bytes: Option<u64>,
36 pub history_retention_seconds: Option<u32>,
37 pub conflict_resolution_type: Option<ConflictResolutionType>,
38 pub replica_index: Option<bool>,
39 pub bucket_type: Option<BucketType>,
40 pub storage_backend: Option<StorageBackend>,
41 pub num_vbuckets: Option<u16>,
42}
43
44impl BucketSettings {
45 pub fn flush_enabled(mut self, flush_enabled: bool) -> Self {
46 self.flush_enabled = Some(flush_enabled);
47 self
48 }
49
50 pub fn ram_quota_mb(mut self, ram_quota_mb: u64) -> Self {
51 self.ram_quota_mb = Some(ram_quota_mb);
52 self
53 }
54
55 pub fn replica_number(mut self, replica_number: u32) -> Self {
56 self.replica_number = Some(replica_number);
57 self
58 }
59
60 pub fn eviction_policy(mut self, eviction_policy: impl Into<EvictionPolicyType>) -> Self {
61 self.eviction_policy = Some(eviction_policy.into());
62 self
63 }
64
65 pub fn max_ttl(mut self, max_ttl: Duration) -> Self {
66 self.max_ttl = Some(max_ttl);
67 self
68 }
69
70 pub fn compression_mode(mut self, compression_mode: impl Into<CompressionMode>) -> Self {
71 self.compression_mode = Some(compression_mode.into());
72 self
73 }
74
75 pub fn durability_min_level(
76 mut self,
77 durability_min_level: impl Into<DurabilityLevel>,
78 ) -> Self {
79 self.durability_min_level = Some(durability_min_level.into());
80 self
81 }
82
83 pub fn history_retention_collection_default(
84 mut self,
85 history_retention_collection_default: bool,
86 ) -> Self {
87 self.history_retention_collection_default = Some(history_retention_collection_default);
88 self
89 }
90
91 pub fn history_retention_bytes(mut self, history_retention_bytes: u64) -> Self {
92 self.history_retention_bytes = Some(history_retention_bytes);
93 self
94 }
95
96 pub fn history_retention_seconds(mut self, history_retention_seconds: u32) -> Self {
97 self.history_retention_seconds = Some(history_retention_seconds);
98 self
99 }
100
101 pub fn conflict_resolution_type(
102 mut self,
103 conflict_resolution_type: impl Into<ConflictResolutionType>,
104 ) -> Self {
105 self.conflict_resolution_type = Some(conflict_resolution_type.into());
106 self
107 }
108
109 pub fn replica_index(mut self, replica_index: bool) -> Self {
110 self.replica_index = Some(replica_index);
111 self
112 }
113
114 pub fn bucket_type(mut self, bucket_type: impl Into<BucketType>) -> Self {
115 self.bucket_type = Some(bucket_type.into());
116 self
117 }
118
119 pub fn storage_backend(mut self, storage_backend: impl Into<StorageBackend>) -> Self {
120 self.storage_backend = Some(storage_backend.into());
121 self
122 }
123
124 pub fn num_vbuckets(mut self, num_vbuckets: u16) -> Self {
125 self.num_vbuckets = Some(num_vbuckets);
126 self
127 }
128}
129
130#[derive(Debug, Clone, PartialOrd, PartialEq)]
131pub struct BucketDef {
132 pub name: String,
133 pub bucket_settings: BucketSettings,
134}
135
136impl BucketDef {
137 pub fn new(name: String, bucket_settings: BucketSettings) -> Self {
138 Self {
139 name,
140 bucket_settings,
141 }
142 }
143}
144
145impl From<BucketSettingsJson> for BucketDef {
146 fn from(settings: BucketSettingsJson) -> Self {
147 Self {
148 name: settings.name,
149 bucket_settings: BucketSettings {
150 flush_enabled: settings.controllers.as_ref().map(|c| {
151 if let Some(f) = &c.flush {
152 !f.is_empty()
153 } else {
154 false
155 }
156 }),
157 ram_quota_mb: Some(settings.quota.raw_ram / 1024 / 1024),
158 replica_number: settings.replica_number,
159 eviction_policy: settings.eviction_policy,
160 max_ttl: settings.max_ttl.map(|d| Duration::from_secs(d as u64)),
161 compression_mode: settings.compression_mode,
162 durability_min_level: settings.durability_min_level,
163 history_retention_collection_default: settings.history_retention_collection_default,
164 history_retention_bytes: settings.history_retention_bytes,
165 history_retention_seconds: settings.history_retention_seconds,
166 conflict_resolution_type: settings.conflict_resolution_type,
167 replica_index: settings.replica_index,
168 bucket_type: settings.bucket_type,
169 storage_backend: settings.storage_backend,
170 num_vbuckets: settings.num_vbuckets,
171 },
172 }
173 }
174}
175
176#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
177pub struct BucketType(InnerBucketType);
178
179impl BucketType {
180 pub const COUCHBASE: BucketType = BucketType(InnerBucketType::Couchbase);
181
182 pub const EPHEMERAL: BucketType = BucketType(InnerBucketType::Ephemeral);
183
184 pub(crate) fn other(val: String) -> BucketType {
185 BucketType(InnerBucketType::Other(val))
186 }
187}
188
189impl Display for BucketType {
190 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
191 match &self.0 {
192 InnerBucketType::Couchbase => write!(f, "membase"),
193 InnerBucketType::Ephemeral => write!(f, "ephemeral"),
194 InnerBucketType::Other(val) => write!(f, "unknown({val})"),
195 }
196 }
197}
198
199#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
200pub(crate) enum InnerBucketType {
201 Couchbase,
202 Ephemeral,
203 Other(String),
204}
205
206#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
207pub struct EvictionPolicyType(InnerEvictionPolicyType);
208
209impl EvictionPolicyType {
210 pub const VALUE_ONLY: EvictionPolicyType =
211 EvictionPolicyType(InnerEvictionPolicyType::ValueOnly);
212
213 pub const FULL: EvictionPolicyType = EvictionPolicyType(InnerEvictionPolicyType::Full);
214
215 pub const NOT_RECENTLY_USED: EvictionPolicyType =
216 EvictionPolicyType(InnerEvictionPolicyType::NotRecentlyUsed);
217
218 pub const NO_EVICTION: EvictionPolicyType =
219 EvictionPolicyType(InnerEvictionPolicyType::NoEviction);
220
221 pub(crate) fn other(val: String) -> EvictionPolicyType {
222 EvictionPolicyType(InnerEvictionPolicyType::Other(val))
223 }
224}
225
226impl Display for EvictionPolicyType {
227 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
228 match &self.0 {
229 InnerEvictionPolicyType::ValueOnly => write!(f, "valueOnly"),
230 InnerEvictionPolicyType::Full => write!(f, "fullEviction"),
231 InnerEvictionPolicyType::NotRecentlyUsed => write!(f, "nruEviction"),
232 InnerEvictionPolicyType::NoEviction => write!(f, "noEviction"),
233 InnerEvictionPolicyType::Other(val) => write!(f, "unknown({val})"),
234 }
235 }
236}
237
238#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
239pub(crate) enum InnerEvictionPolicyType {
240 ValueOnly,
241 Full,
242 NotRecentlyUsed,
243 NoEviction,
244 Other(String),
245}
246
247#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
248pub struct CompressionMode(InnerCompressionMode);
249
250impl CompressionMode {
251 pub const OFF: CompressionMode = CompressionMode(InnerCompressionMode::Off);
252
253 pub const PASSIVE: CompressionMode = CompressionMode(InnerCompressionMode::Passive);
254
255 pub const ACTIVE: CompressionMode = CompressionMode(InnerCompressionMode::Active);
256
257 pub(crate) fn other(val: String) -> CompressionMode {
258 CompressionMode(InnerCompressionMode::Other(val))
259 }
260}
261
262impl Display for CompressionMode {
263 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
264 match &self.0 {
265 InnerCompressionMode::Off => write!(f, "off"),
266 InnerCompressionMode::Passive => write!(f, "passive"),
267 InnerCompressionMode::Active => write!(f, "active"),
268 InnerCompressionMode::Other(val) => write!(f, "unknown({val})"),
269 }
270 }
271}
272
273#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
274pub(crate) enum InnerCompressionMode {
275 Off,
276 Passive,
277 Active,
278 Other(String),
279}
280
281#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
282pub struct DurabilityLevel(InnerDurabilityLevel);
283
284impl DurabilityLevel {
285 pub const NONE: DurabilityLevel = DurabilityLevel(InnerDurabilityLevel::None);
286
287 pub const MAJORITY: DurabilityLevel = DurabilityLevel(InnerDurabilityLevel::Majority);
288
289 pub const MAJORITY_AND_PERSIST_ACTIVE: DurabilityLevel =
290 DurabilityLevel(InnerDurabilityLevel::MajorityAndPersistActive);
291
292 pub const PERSIST_TO_MAJORITY: DurabilityLevel =
293 DurabilityLevel(InnerDurabilityLevel::PersistToMajority);
294
295 pub(crate) fn other(val: String) -> DurabilityLevel {
296 DurabilityLevel(InnerDurabilityLevel::Other(val))
297 }
298}
299
300impl Display for DurabilityLevel {
301 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
302 match &self.0 {
303 InnerDurabilityLevel::None => write!(f, "none"),
304 InnerDurabilityLevel::Majority => write!(f, "majority"),
305 InnerDurabilityLevel::MajorityAndPersistActive => write!(f, "majorityAndPersistActive"),
306 InnerDurabilityLevel::PersistToMajority => write!(f, "persistToMajority"),
307 InnerDurabilityLevel::Other(val) => write!(f, "unknown({val})"),
308 }
309 }
310}
311
312#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
313pub(crate) enum InnerDurabilityLevel {
314 None,
315 Majority,
316 MajorityAndPersistActive,
317 PersistToMajority,
318 Other(String),
319}
320
321#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
322pub struct ConflictResolutionType(InnerConflictResolutionType);
323
324impl ConflictResolutionType {
325 pub const SEQUENCE_NUMBER: ConflictResolutionType =
326 ConflictResolutionType(InnerConflictResolutionType::SequenceNumber);
327
328 pub const TIMESTAMP: ConflictResolutionType =
329 ConflictResolutionType(InnerConflictResolutionType::Timestamp);
330
331 pub const CUSTOM: ConflictResolutionType =
332 ConflictResolutionType(InnerConflictResolutionType::Custom);
333
334 pub(crate) fn other(val: String) -> ConflictResolutionType {
335 ConflictResolutionType(InnerConflictResolutionType::Other(val))
336 }
337}
338
339impl Display for ConflictResolutionType {
340 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
341 match &self.0 {
342 InnerConflictResolutionType::SequenceNumber => write!(f, "seqno"),
343 InnerConflictResolutionType::Timestamp => write!(f, "lww"),
344 InnerConflictResolutionType::Custom => write!(f, "custom"),
345 InnerConflictResolutionType::Other(val) => write!(f, "unknown({val})"),
346 }
347 }
348}
349
350#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
351pub(crate) enum InnerConflictResolutionType {
352 SequenceNumber,
353 Timestamp,
354 Custom,
355 Other(String),
356}
357
358#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
359pub struct StorageBackend(InnerStorageBackend);
360
361impl StorageBackend {
362 pub const COUCHSTORE: StorageBackend = StorageBackend(InnerStorageBackend::Couchstore);
363
364 pub const MAGMA: StorageBackend = StorageBackend(InnerStorageBackend::Magma);
365
366 pub(crate) fn other(val: String) -> StorageBackend {
367 StorageBackend(InnerStorageBackend::Other(val))
368 }
369}
370
371impl Display for StorageBackend {
372 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
373 match &self.0 {
374 InnerStorageBackend::Couchstore => write!(f, "couchstore"),
375 InnerStorageBackend::Magma => write!(f, "magma"),
376 InnerStorageBackend::Other(val) => write!(f, "unknown({val})"),
377 }
378 }
379}
380
381#[derive(Clone, Debug, Ord, PartialOrd, Eq, PartialEq, Hash)]
382pub(crate) enum InnerStorageBackend {
383 Couchstore,
384 Magma,
385 Other(String),
386}
387
388pub(crate) fn encode_bucket_settings(serializer: &mut Serializer<String>, opts: &BucketSettings) {
389 if let Some(flush) = opts.flush_enabled {
390 serializer.append_pair("flushEnabled", if flush { "1" } else { "0" });
391 }
392 if let Some(quota) = opts.ram_quota_mb {
393 serializer.append_pair("ramQuotaMB", quota.to_string().as_str());
394 }
395 if let Some(num) = opts.replica_number {
396 serializer.append_pair("replicaNumber", num.to_string().as_str());
397 }
398 if let Some(eviction_policy) = &opts.eviction_policy {
399 serializer.append_pair("evictionPolicy", eviction_policy.to_string().as_str());
400 }
401 if let Some(max_ttl) = &opts.max_ttl {
402 serializer.append_pair("maxTTL", max_ttl.as_secs().to_string().as_str());
403 }
404 if let Some(compression_mode) = &opts.compression_mode {
405 serializer.append_pair("compressionMode", compression_mode.to_string().as_str());
406 }
407 if let Some(durability_min_level) = &opts.durability_min_level {
408 serializer.append_pair(
409 "durabilityMinLevel",
410 durability_min_level.to_string().as_str(),
411 );
412 }
413 if let Some(retention) = opts.history_retention_bytes {
414 serializer.append_pair("historyRetentionBytes", retention.to_string().as_str());
415 }
416 if let Some(retention) = opts.history_retention_seconds {
417 serializer.append_pair("historyRetentionSeconds", retention.to_string().as_str());
418 }
419 if let Some(history_retention_collection_default) = &opts.history_retention_collection_default {
420 serializer.append_pair(
421 "historyRetentionCollectionDefault",
422 history_retention_collection_default.to_string().as_str(),
423 );
424 }
425 if let Some(conflict_resolution_type) = &opts.conflict_resolution_type {
426 serializer.append_pair(
427 "conflictResolutionType",
428 conflict_resolution_type.to_string().as_str(),
429 );
430 }
431 if let Some(index) = opts.replica_index {
432 serializer.append_pair("replicaIndex", if index { "1" } else { "0" });
433 }
434 if let Some(bucket_type) = &opts.bucket_type {
435 serializer.append_pair("bucketType", bucket_type.to_string().as_str());
436 }
437 if let Some(storage_backend) = &opts.storage_backend {
438 serializer.append_pair("storageBackend", storage_backend.to_string().as_str());
439 }
440 if let Some(num_vbuckets) = opts.num_vbuckets {
441 serializer.append_pair("numVBuckets", num_vbuckets.to_string().as_str());
442 }
443}