use crate::bson::{Binary, Bson, RawDocumentBuf};
use macro_magic::export_tokens;
use mongocrypt::ctx::Algorithm;
use serde::Serialize;
use serde_with::skip_serializing_none;
use typed_builder::TypedBuilder;
use crate::{
action::{deeplink, export_doc, option_setters, options_doc},
client_encryption::ClientEncryption,
};
impl ClientEncryption {
#[deeplink]
#[options_doc(encrypt)]
pub fn encrypt(
&self,
value: impl Into<crate::bson::RawBson>,
key: impl Into<EncryptKey>,
algorithm: Algorithm,
) -> Encrypt<'_> {
Encrypt {
client_enc: self,
mode: Value {
value: value.into(),
},
key: key.into(),
algorithm,
options: None,
}
}
#[deeplink]
#[options_doc(encrypt_expr)]
pub fn encrypt_expression(
&self,
expression: RawDocumentBuf,
key: impl Into<EncryptKey>,
) -> Encrypt<'_, Expression> {
Encrypt {
client_enc: self,
mode: Expression { value: expression },
key: key.into(),
algorithm: Algorithm::Range,
options: None,
}
}
}
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum EncryptKey {
Id(Binary),
AltName(String),
}
impl From<Binary> for EncryptKey {
fn from(bin: Binary) -> Self {
Self::Id(bin)
}
}
impl From<String> for EncryptKey {
fn from(s: String) -> Self {
Self::AltName(s)
}
}
#[must_use]
pub struct Encrypt<'a, Mode = Value> {
pub(crate) client_enc: &'a ClientEncryption,
pub(crate) mode: Mode,
pub(crate) key: EncryptKey,
pub(crate) algorithm: Algorithm,
pub(crate) options: Option<EncryptOptions>,
}
pub struct Value {
pub(crate) value: crate::bson::RawBson,
}
pub struct Expression {
pub(crate) value: RawDocumentBuf,
}
#[derive(Debug, Clone, Default, TypedBuilder)]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[export_tokens]
pub struct EncryptOptions {
pub contention_factor: Option<i64>,
pub query_type: Option<String>,
pub range_options: Option<RangeOptions>,
#[cfg(feature = "text-indexes-unstable")]
pub text_options: Option<TextOptions>,
}
#[skip_serializing_none]
#[derive(Clone, Default, Debug, Serialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
pub struct RangeOptions {
pub min: Option<Bson>,
pub max: Option<Bson>,
pub trim_factor: Option<i32>,
pub sparsity: Option<i64>,
pub precision: Option<i32>,
}
#[skip_serializing_none]
#[derive(Clone, Default, Debug, Serialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[cfg(feature = "text-indexes-unstable")]
pub struct TextOptions {
pub substring: Option<SubstringOptions>,
pub prefix: Option<PrefixOptions>,
pub suffix: Option<SuffixOptions>,
pub case_sensitive: bool,
pub diacritic_sensitive: bool,
}
#[derive(Clone, Default, Debug, Serialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[cfg(feature = "text-indexes-unstable")]
pub struct SubstringOptions {
#[serde(rename = "strMaxLength")]
pub max_string_length: i32,
#[serde(rename = "strMinQueryLength")]
pub min_query_length: i32,
#[serde(rename = "strMaxQueryLength")]
pub max_query_length: i32,
}
#[derive(Clone, Default, Debug, Serialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[cfg(feature = "text-indexes-unstable")]
pub struct PrefixOptions {
#[serde(rename = "strMinQueryLength")]
pub min_query_length: i32,
#[serde(rename = "strMaxQueryLength")]
pub max_query_length: i32,
}
#[derive(Clone, Default, Debug, Serialize, TypedBuilder)]
#[serde(rename_all = "camelCase")]
#[builder(field_defaults(default, setter(into)))]
#[non_exhaustive]
#[cfg(feature = "text-indexes-unstable")]
pub struct SuffixOptions {
#[serde(rename = "strMinQueryLength")]
pub min_query_length: i32,
#[serde(rename = "strMaxQueryLength")]
pub max_query_length: i32,
}
#[option_setters(EncryptOptions, skip = [query_type])]
#[export_doc(encrypt, extra = [query_type])]
#[export_doc(encrypt_expr)]
impl<Mode> Encrypt<'_, Mode> {}
impl Encrypt<'_, Value> {
pub fn query_type(mut self, value: impl Into<String>) -> Self {
self.options().query_type = Some(value.into());
self
}
}