use std::time::Duration;
use crate::bson::doc;
use macro_magic::export_tokens;
use serde::{Deserialize, Serialize};
use serde_with::skip_serializing_none;
use typed_builder::TypedBuilder;
use crate::{
bson::{Bson, Document},
concern::{ReadConcern, WriteConcern},
options::{Collation, CursorType},
selection_criteria::SelectionCriteria,
serde_util,
};
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
pub struct DatabaseOptions {
pub selection_criteria: Option<SelectionCriteria>,
pub read_concern: Option<ReadConcern>,
pub write_concern: Option<WriteConcern>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[export_tokens]
pub struct CreateCollectionOptions {
pub capped: Option<bool>,
#[serde(
serialize_with = "serde_util::serialize_u64_option_as_i64",
deserialize_with = "serde_util::deserialize_option_u64_from_bson_number",
default
)]
pub size: Option<u64>,
#[serde(serialize_with = "serde_util::serialize_u64_option_as_i64")]
pub max: Option<u64>,
pub storage_engine: Option<Document>,
pub validator: Option<Document>,
pub validation_level: Option<ValidationLevel>,
pub validation_action: Option<ValidationAction>,
pub view_on: Option<String>,
pub pipeline: Option<Vec<Document>>,
pub collation: Option<Collation>,
#[serde(skip_serializing)]
pub write_concern: Option<WriteConcern>,
pub index_option_defaults: Option<IndexOptionDefaults>,
pub timeseries: Option<TimeseriesOptions>,
#[serde(default, with = "serde_util::duration_option_as_int_seconds")]
pub expire_after_seconds: Option<Duration>,
pub change_stream_pre_and_post_images: Option<ChangeStreamPreAndPostImages>,
#[serde(default, deserialize_with = "ClusteredIndex::deserialize_self_or_true")]
pub clustered_index: Option<ClusteredIndex>,
pub comment: Option<Bson>,
#[cfg(feature = "in-use-encryption")]
pub encrypted_fields: Option<Document>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub enum ValidationLevel {
Off,
Strict,
Moderate,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub enum ValidationAction {
Error,
Warn,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct ClusteredIndex {
pub key: Document,
pub unique: bool,
pub name: Option<String>,
pub v: Option<i32>,
}
impl Default for ClusteredIndex {
fn default() -> Self {
Self {
key: doc! { "_id": 1 },
unique: true,
name: None,
v: None,
}
}
}
impl ClusteredIndex {
fn deserialize_self_or_true<'de, D>(deserializer: D) -> Result<Option<ClusteredIndex>, D::Error>
where
D: serde::Deserializer<'de>,
{
#[derive(Debug, Deserialize)]
#[serde(untagged)]
enum ValueUnion {
Bool(bool),
ClusteredIndex(ClusteredIndex),
}
let value_option: Option<ValueUnion> = Deserialize::deserialize(deserializer)?;
value_option
.map(|value| match value {
ValueUnion::Bool(true) => Ok(ClusteredIndex::default()),
ValueUnion::Bool(false) => Err(serde::de::Error::custom(
"if clusteredIndex is a boolean it must be `true`",
)),
ValueUnion::ClusteredIndex(value) => Ok(value),
})
.transpose()
}
}
#[derive(Clone, Debug, TypedBuilder, PartialEq, Serialize, Deserialize)]
#[builder(field_defaults(default, setter(into)))]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct IndexOptionDefaults {
pub storage_engine: Document,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
pub struct TimeseriesOptions {
pub time_field: String,
pub meta_field: Option<String>,
pub granularity: Option<TimeseriesGranularity>,
#[serde(
default,
with = "serde_util::duration_option_as_int_seconds",
rename = "bucketMaxSpanSeconds"
)]
pub bucket_max_span: Option<Duration>,
#[serde(
default,
with = "serde_util::duration_option_as_int_seconds",
rename = "bucketRoundingSeconds"
)]
pub bucket_rounding: Option<Duration>,
}
#[derive(Clone, Debug, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub enum TimeseriesGranularity {
Seconds,
Minutes,
Hours,
}
#[derive(Clone, Debug, Default, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[export_tokens]
pub struct DropDatabaseOptions {
#[serde(skip_serializing)]
pub write_concern: Option<WriteConcern>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[export_tokens]
pub struct ListCollectionsOptions {
#[serde(
serialize_with = "serde_util::serialize_u32_option_as_batch_size",
rename(serialize = "cursor")
)]
pub batch_size: Option<u32>,
pub comment: Option<Bson>,
pub filter: Option<Document>,
pub authorized_collections: Option<bool>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[export_tokens]
pub struct ListDatabasesOptions {
pub authorized_databases: Option<bool>,
pub comment: Option<Bson>,
pub filter: Option<Document>,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
pub struct ChangeStreamPreAndPostImages {
pub enabled: bool,
}
#[derive(Clone, Debug, Default, TypedBuilder)]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[export_tokens]
pub struct RunCommandOptions {
pub selection_criteria: Option<SelectionCriteria>,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[builder(field_defaults(default, setter(into)))]
#[serde(rename_all = "camelCase")]
#[serde(default)]
#[non_exhaustive]
#[export_tokens]
pub struct RunCursorCommandOptions {
pub selection_criteria: Option<SelectionCriteria>,
pub cursor_type: Option<CursorType>,
pub batch_size: Option<u32>,
#[serde(rename = "maxtime", alias = "maxTimeMS")]
#[serde(deserialize_with = "serde_util::deserialize_duration_option_from_u64_millis")]
pub max_time: Option<Duration>,
pub comment: Option<Bson>,
}