1pub mod options;
2
3use crate::bson::Document;
4
5use self::options::*;
6use serde::{Deserialize, Serialize};
7
8use typed_builder::TypedBuilder;
9
10#[derive(Clone, Debug, Default, Deserialize, TypedBuilder, Serialize)]
12#[builder(field_defaults(default, setter(into)))]
13#[serde(rename_all = "camelCase")]
14#[non_exhaustive]
15pub struct IndexModel {
16 #[serde(rename = "key")]
19 pub keys: Document,
20
21 #[serde(flatten)]
23 pub options: Option<IndexOptions>,
24}
25
26impl IndexModel {
27 pub(crate) fn update_name(&mut self) {
29 if self
30 .options
31 .as_ref()
32 .and_then(|o| o.name.as_ref())
33 .is_none()
34 {
35 fn format_kv(kv: (&String, &crate::bson::Bson)) -> String {
36 if let crate::bson::Bson::String(s) = kv.1 {
37 format!("{}_{}", kv.0, s)
38 } else {
39 format!("{}_{}", kv.0, kv.1)
40 }
41 }
42 let key_names: Vec<String> = self.keys.iter().map(format_kv).collect();
43 self.options.get_or_insert(IndexOptions::default()).name = Some(key_names.join("_"));
44 }
45 }
46
47 pub(crate) fn get_name(&self) -> Option<String> {
48 self.options.as_ref().and_then(|o| o.name.as_ref()).cloned()
49 }
50
51 #[cfg(test)]
52 pub(crate) fn is_unique(&self) -> bool {
53 self.options
54 .as_ref()
55 .and_then(|o| o.unique)
56 .unwrap_or(false)
57 }
58}