Skip to main content

mongodb/
index.rs

1pub mod options;
2
3use crate::bson::Document;
4
5use self::options::*;
6use serde::{Deserialize, Serialize};
7
8use typed_builder::TypedBuilder;
9
10/// Specifies the fields and options for an index. For more information, see the [documentation](https://www.mongodb.com/docs/manual/indexes/).
11#[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    /// Specifies the index’s fields. For each field, specify a key-value pair in which the key is
17    /// the name of the field to index and the value is index type.
18    #[serde(rename = "key")]
19    pub keys: Document,
20
21    /// The options for the index.
22    #[serde(flatten)]
23    pub options: Option<IndexOptions>,
24}
25
26impl IndexModel {
27    /// If the client did not specify a name, generate and set it. Otherwise, do nothing.
28    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}