use std::time::Duration;
use crate::{
bson::{serde_helpers, Document},
bson_util,
collation::Collation,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use typed_builder::TypedBuilder;
#[serde_with::skip_serializing_none]
#[derive(Clone, Debug, Default, Deserialize, Serialize, TypedBuilder)]
#[builder(field_defaults(default, setter(into)))]
#[serde(rename_all = "camelCase")]
#[non_exhaustive]
pub struct IndexOptions {
pub background: Option<bool>,
#[serde(
rename = "expireAfterSeconds",
default,
deserialize_with = "bson_util::deserialize_duration_option_from_u64_seconds",
serialize_with = "bson_util::serialize_duration_option_as_int_secs"
)]
pub expire_after: Option<Duration>,
pub name: Option<String>,
pub sparse: Option<bool>,
pub storage_engine: Option<Document>,
pub unique: Option<bool>,
#[serde(rename = "v")]
pub version: Option<IndexVersion>,
#[serde(rename = "default_language")]
pub default_language: Option<String>,
#[serde(rename = "language_override")]
pub language_override: Option<String>,
pub text_index_version: Option<TextIndexVersion>,
pub weights: Option<Document>,
#[serde(rename = "2dsphereIndexVersion")]
pub sphere_2d_index_version: Option<Sphere2DIndexVersion>,
#[serde(serialize_with = "bson_util::serialize_u32_option_as_i32")]
pub bits: Option<u32>,
pub max: Option<f64>,
pub min: Option<f64>,
#[serde(serialize_with = "bson_util::serialize_u32_option_as_i32")]
pub bucket_size: Option<u32>,
pub partial_filter_expression: Option<Document>,
pub collation: Option<Collation>,
pub wildcard_projection: Option<Document>,
pub hidden: Option<bool>,
#[builder(default, setter(skip))]
clustered: Option<bool>,
}
impl IndexOptions {
pub fn clustered(&self) -> Option<bool> {
self.clustered
}
}
#[derive(Clone, Debug)]
#[non_exhaustive]
pub enum IndexVersion {
#[deprecated]
V0,
V1,
V2,
Custom(u32),
}
#[allow(deprecated)]
impl Serialize for IndexVersion {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
IndexVersion::V0 => serializer.serialize_i32(0),
IndexVersion::V1 => serializer.serialize_i32(1),
IndexVersion::V2 => serializer.serialize_i32(2),
IndexVersion::Custom(i) => serde_helpers::serialize_u32_as_i32(i, serializer),
}
}
}
#[allow(deprecated)]
impl<'de> Deserialize<'de> for IndexVersion {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
match i32::deserialize(deserializer)? {
0 => Ok(IndexVersion::V0),
1 => Ok(IndexVersion::V1),
2 => Ok(IndexVersion::V2),
i => Ok(IndexVersion::Custom(i as u32)),
}
}
}
#[derive(Clone, Debug)]
pub enum TextIndexVersion {
V1,
V2,
V3,
Custom(u32),
}
impl Serialize for TextIndexVersion {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
TextIndexVersion::V1 => serializer.serialize_i32(1),
TextIndexVersion::V2 => serializer.serialize_i32(2),
TextIndexVersion::V3 => serializer.serialize_i32(3),
TextIndexVersion::Custom(i) => serde_helpers::serialize_u32_as_i32(i, serializer),
}
}
}
impl<'de> Deserialize<'de> for TextIndexVersion {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
match i32::deserialize(deserializer)? {
1 => Ok(TextIndexVersion::V1),
2 => Ok(TextIndexVersion::V2),
3 => Ok(TextIndexVersion::V3),
i => Ok(TextIndexVersion::Custom(i as u32)),
}
}
}
#[derive(Clone, Debug)]
pub enum Sphere2DIndexVersion {
V2,
V3,
Custom(u32),
}
impl Serialize for Sphere2DIndexVersion {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match self {
Sphere2DIndexVersion::V2 => serializer.serialize_i32(2),
Sphere2DIndexVersion::V3 => serializer.serialize_i32(3),
Sphere2DIndexVersion::Custom(i) => serde_helpers::serialize_u32_as_i32(i, serializer),
}
}
}
impl<'de> Deserialize<'de> for Sphere2DIndexVersion {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
match i32::deserialize(deserializer)? {
2 => Ok(Sphere2DIndexVersion::V2),
3 => Ok(Sphere2DIndexVersion::V3),
i => Ok(Sphere2DIndexVersion::Custom(i as u32)),
}
}
}