use std::time::Duration;
use serde::{Deserialize, Serialize, Serializer};
use serde_with::skip_serializing_none;
use typed_builder::TypedBuilder;
use crate::{
bson::{doc, Bson, Document},
bson_util::{
deserialize_duration_from_u64_millis,
serialize_batch_size,
serialize_duration_as_int_millis,
serialize_u32_as_i32,
},
concern::{ReadConcern, WriteConcern},
options::Collation,
selection_criteria::SelectionCriteria,
};
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct CollectionOptions {
#[builder(default)]
pub selection_criteria: Option<SelectionCriteria>,
#[builder(default)]
pub read_concern: Option<ReadConcern>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
}
#[derive(Clone, Debug, Deserialize)]
#[non_exhaustive]
pub enum ReturnDocument {
After,
Before,
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
#[non_exhaustive]
pub enum Hint {
Keys(Document),
Name(String),
}
impl Hint {
pub(crate) fn to_bson(&self) -> Bson {
match self {
Hint::Keys(ref d) => Bson::Document(d.clone()),
Hint::Name(ref s) => Bson::String(s.clone()),
}
}
}
#[derive(Debug, Clone, Copy)]
#[non_exhaustive]
pub enum CursorType {
NonTailable,
Tailable,
TailableAwait,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct InsertOneOptions {
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Default, TypedBuilder, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct InsertManyOptions {
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub ordered: Option<bool>,
#[builder(default)]
#[serde(skip_deserializing)]
pub write_concern: Option<WriteConcern>,
}
impl InsertManyOptions {
pub(crate) fn from_insert_one_options(options: InsertOneOptions) -> Self {
Self {
bypass_document_validation: options.bypass_document_validation,
ordered: None,
write_concern: options.write_concern,
}
}
}
#[derive(Clone, Debug, Deserialize, Serialize)]
#[serde(untagged)]
#[non_exhaustive]
pub enum UpdateModifications {
Document(Document),
Pipeline(Vec<Document>),
}
impl UpdateModifications {
pub(crate) fn to_bson(&self) -> Bson {
match self {
UpdateModifications::Document(ref d) => Bson::Document(d.clone()),
UpdateModifications::Pipeline(ref p) => {
Bson::Array(p.iter().map(|d| Bson::Document(d.clone())).collect())
}
}
}
}
impl From<Document> for UpdateModifications {
fn from(item: Document) -> Self {
UpdateModifications::Document(item)
}
}
impl From<Vec<Document>> for UpdateModifications {
fn from(item: Vec<Document>) -> Self {
UpdateModifications::Pipeline(item)
}
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct UpdateOptions {
#[builder(default)]
pub array_filters: Option<Vec<Document>>,
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub upsert: Option<bool>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub hint: Option<Hint>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
}
impl UpdateOptions {
pub(crate) fn from_replace_options(options: ReplaceOptions) -> Self {
Self {
bypass_document_validation: options.bypass_document_validation,
upsert: options.upsert,
hint: options.hint,
write_concern: options.write_concern,
collation: options.collation,
..Default::default()
}
}
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct ReplaceOptions {
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub upsert: Option<bool>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub hint: Option<Hint>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
}
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct DeleteOptions {
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
#[builder(default)]
pub hint: Option<Hint>,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[non_exhaustive]
pub struct FindOneAndDeleteOptions {
#[builder(default)]
pub max_time: Option<Duration>,
#[builder(default)]
pub projection: Option<Document>,
#[builder(default)]
pub sort: Option<Document>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub hint: Option<Hint>,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[non_exhaustive]
pub struct FindOneAndReplaceOptions {
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub max_time: Option<Duration>,
#[builder(default)]
pub projection: Option<Document>,
#[builder(default)]
pub return_document: Option<ReturnDocument>,
#[builder(default)]
pub sort: Option<Document>,
#[builder(default)]
pub upsert: Option<bool>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub hint: Option<Hint>,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[non_exhaustive]
pub struct FindOneAndUpdateOptions {
#[builder(default)]
pub array_filters: Option<Vec<Document>>,
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub max_time: Option<Duration>,
#[builder(default)]
pub projection: Option<Document>,
#[builder(default)]
pub return_document: Option<ReturnDocument>,
#[builder(default)]
pub sort: Option<Document>,
#[builder(default)]
pub upsert: Option<bool>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub hint: Option<Hint>,
}
#[skip_serializing_none]
#[serde(rename_all = "camelCase")]
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[non_exhaustive]
pub struct AggregateOptions {
#[builder(default)]
pub allow_disk_use: Option<bool>,
#[builder(default)]
#[serde(serialize_with = "serialize_batch_size", rename(serialize = "cursor"))]
pub batch_size: Option<u32>,
#[builder(default)]
pub bypass_document_validation: Option<bool>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub comment: Option<String>,
#[builder(default)]
pub hint: Option<Hint>,
#[builder(default)]
#[serde(
skip_serializing,
deserialize_with = "deserialize_duration_from_u64_millis"
)]
pub max_await_time: Option<Duration>,
#[builder(default)]
#[serde(
serialize_with = "serialize_duration_as_int_millis",
rename = "maxTimeMS",
deserialize_with = "deserialize_duration_from_u64_millis"
)]
pub max_time: Option<Duration>,
#[builder(default)]
pub read_concern: Option<ReadConcern>,
#[builder(default)]
#[serde(skip_serializing)]
#[serde(rename = "readPreference")]
pub selection_criteria: Option<SelectionCriteria>,
#[builder(default)]
pub write_concern: Option<WriteConcern>,
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct CountOptions {
#[builder(default)]
pub hint: Option<Hint>,
#[builder(default)]
pub limit: Option<i64>,
#[builder(default)]
#[serde(deserialize_with = "deserialize_duration_from_u64_millis")]
pub max_time: Option<Duration>,
#[builder(default)]
pub skip: Option<i64>,
#[builder(default)]
pub collation: Option<Collation>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Default, Deserialize, TypedBuilder, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct EstimatedDocumentCountOptions {
#[builder(default)]
#[serde(
serialize_with = "serialize_duration_as_int_millis",
rename = "maxTimeMS",
deserialize_with = "deserialize_duration_from_u64_millis"
)]
pub max_time: Option<Duration>,
#[builder(default)]
#[serde(skip_serializing)]
pub selection_criteria: Option<SelectionCriteria>,
#[builder(default)]
pub read_concern: Option<ReadConcern>,
}
#[serde_with::skip_serializing_none]
#[derive(Debug, Default, Deserialize, TypedBuilder, Serialize, Clone)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct DistinctOptions {
#[builder(default)]
#[serde(
serialize_with = "serialize_duration_as_int_millis",
rename = "maxTimeMS",
deserialize_with = "deserialize_duration_from_u64_millis"
)]
pub max_time: Option<Duration>,
#[builder(default)]
#[serde(skip_serializing)]
pub selection_criteria: Option<SelectionCriteria>,
#[builder(default)]
pub read_concern: Option<ReadConcern>,
#[builder(default)]
pub collation: Option<Collation>,
}
#[skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct FindOptions {
#[builder(default)]
pub allow_disk_use: Option<bool>,
#[builder(default)]
pub allow_partial_results: Option<bool>,
#[builder(default)]
#[serde(serialize_with = "serialize_u32_as_i32")]
pub batch_size: Option<u32>,
#[builder(default)]
pub comment: Option<String>,
#[builder(default)]
#[serde(skip)]
pub cursor_type: Option<CursorType>,
#[builder(default)]
pub hint: Option<Hint>,
#[builder(default)]
#[serde(serialize_with = "serialize_absolute_value")]
pub limit: Option<i64>,
#[builder(default)]
pub max: Option<Document>,
#[builder(default)]
#[serde(skip)]
pub max_await_time: Option<Duration>,
#[builder(default)]
pub max_scan: Option<i64>,
#[builder(default)]
#[serde(
rename = "maxTimeMS",
serialize_with = "serialize_duration_as_int_millis"
)]
pub max_time: Option<Duration>,
#[builder(default)]
pub min: Option<Document>,
#[builder(default)]
pub no_cursor_timeout: Option<bool>,
#[builder(default)]
pub projection: Option<Document>,
#[builder(default)]
pub read_concern: Option<ReadConcern>,
#[builder(default)]
pub return_key: Option<bool>,
#[builder(default)]
#[serde(skip)]
pub selection_criteria: Option<SelectionCriteria>,
#[builder(default)]
pub show_record_id: Option<bool>,
#[builder(default)]
pub skip: Option<i64>,
#[builder(default)]
pub sort: Option<Document>,
#[builder(default)]
pub collation: Option<Collation>,
}
impl From<FindOneOptions> for FindOptions {
fn from(options: FindOneOptions) -> Self {
FindOptions {
allow_disk_use: None,
allow_partial_results: options.allow_partial_results,
collation: options.collation,
comment: options.comment,
hint: options.hint,
max: options.max,
max_scan: options.max_scan,
max_time: options.max_time,
min: options.min,
projection: options.projection,
read_concern: options.read_concern,
return_key: options.return_key,
selection_criteria: options.selection_criteria,
show_record_id: options.show_record_id,
skip: options.skip,
batch_size: None,
cursor_type: None,
limit: None,
max_await_time: None,
no_cursor_timeout: None,
sort: options.sort,
}
}
}
fn serialize_absolute_value<S>(
val: &Option<i64>,
serializer: S,
) -> std::result::Result<S::Ok, S::Error>
where
S: Serializer,
{
match val {
Some(v) => serializer.serialize_i64(v.abs()),
None => serializer.serialize_none(),
}
}
#[derive(Clone, Debug, Default, Deserialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct FindOneOptions {
#[builder(default)]
pub allow_partial_results: Option<bool>,
#[builder(default)]
pub collation: Option<Collation>,
#[builder(default)]
pub comment: Option<String>,
#[builder(default)]
pub hint: Option<Hint>,
#[builder(default)]
pub max: Option<Document>,
#[builder(default)]
pub max_scan: Option<i64>,
#[builder(default)]
#[serde(deserialize_with = "deserialize_duration_from_u64_millis")]
pub max_time: Option<Duration>,
#[builder(default)]
pub min: Option<Document>,
#[builder(default)]
pub projection: Option<Document>,
#[builder(default)]
pub read_concern: Option<ReadConcern>,
#[builder(default)]
pub return_key: Option<bool>,
#[builder(default)]
pub selection_criteria: Option<SelectionCriteria>,
#[builder(default)]
pub show_record_id: Option<bool>,
#[builder(default)]
pub skip: Option<i64>,
#[builder(default)]
pub sort: Option<Document>,
}
#[derive(Debug, Default, TypedBuilder, Serialize)]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct DropCollectionOptions {
#[builder(default)]
pub write_concern: Option<WriteConcern>,
}