1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
//! This module facilitates the building of new indexes as well as the retrieval
//! of existing indexes in ArangoDB.
//! The following types are supported:
//!
//! * Fulltext
//! * Geo
//! * Hash
//! * Persistent
//! * Skiplist
//! * Ttl (Time to live)
//!
//! An index of type [Primary] cannot be created and is only available for
//! the retrieval of existing indexes, as ArangoDB creates a primary index on
//! every collection.
//! For detailed information about ArangoDB indexes, please check out the
//! official ArangoDB [documentation](https://www.arangodb.com/docs/stable/http/indexes.html).
//!
//! [Primary]: https://www.arangodb.com/docs/stable/http/indexes.html#primary-index
use serde::{Deserialize, Serialize};
use typed_builder::TypedBuilder;

pub(crate) const INDEX_API_PATH: &str = "_api/index";

/// Represents an [`Index`] in ArangoDB. The following types are
/// supported:
/// * Fulltext
/// * Geo
/// * Hash
/// * Persistent
/// * Skiplist
/// * Ttl (Time to live)
///
/// As different settings may be applied to different index types, use the
/// [`settings`] field on the index to specify the exact `type` of the index
/// including the required settings.
///
/// # Example
/// ```
/// # use arangors::Connection;
/// # use arangors::index::{IndexSettings, Index};
///
/// # #[cfg_attr(any(feature="reqwest_async"), maybe_async::maybe_async, tokio::main)]
/// # #[cfg_attr(any(feature="surf_async"), maybe_async::maybe_async, async_std::main)]
/// # #[cfg_attr(feature = "blocking", maybe_async::must_be_sync)]
/// # async fn main() -> Result<(),anyhow::Error>{
/// # let conn = Connection::establish_jwt("http://localhost:8529", "username", "password")
/// #     .await
/// #     .unwrap();
/// let database = conn.db("test_db").await.unwrap();
///
/// let index = Index::builder()
///     .name("doc_test_index_name")
///     .fields(vec!["password".to_string()])
///     .settings(IndexSettings::Persistent {
///         unique: true,
///         sparse: false,
///         deduplicate: false,
///     })
///     .build();
///
/// let index = database.create_index("test_collection", &index).await?;
/// let delete_result = database.delete_index(&index.id).await.unwrap();
/// # Ok(())
/// # }
/// ```
/// [`Index`]: struct.Index.html
/// [`settings`]: enum.IndexSettings.html
#[derive(Debug, Clone, Serialize, Deserialize, Default, TypedBuilder)]
#[serde(rename_all = "camelCase")]
pub struct Index {
    #[builder(default)]
    pub fields: Vec<String>,
    #[builder(default, setter(into))]
    pub name: String,
    #[builder(default)]
    pub id: String,
    #[builder(default)]
    pub is_newly_created: Option<bool>,
    #[builder(default)]
    pub selectivity_estimate: Option<f32>,
    #[builder(default)]
    pub in_background: Option<bool>,
    #[serde(flatten)]
    #[builder(default)]
    pub settings: IndexSettings,
}

/// Settings for the different index types. This `enum` also sets the index
/// type.
#[derive(Debug, Clone, Serialize, Deserialize)]
#[serde(rename_all = "camelCase", tag = "type")]
pub enum IndexSettings {
    Primary {
        unique: bool,
        sparse: bool,
    },
    Persistent {
        unique: bool,
        sparse: bool,
        deduplicate: bool,
    },
    Edge {
        unique: bool,
        sparse: bool,
    },
    Hash {
        unique: bool,
        sparse: bool,
        deduplicate: bool,
    },
    Skiplist {
        unique: bool,
        sparse: bool,
        deduplicate: bool,
    },
    #[serde(rename_all = "camelCase")]
    Ttl {
        expire_after: u32,
    },
    #[serde(rename_all = "camelCase")]
    Geo {
        geo_json: bool,
    },
    #[serde(rename_all = "camelCase")]
    Fulltext {
        min_length: u32,
    },
}

impl Default for IndexSettings {
    fn default() -> Self {
        IndexSettings::Persistent {
            unique: false,
            sparse: false,
            deduplicate: false,
        }
    }
}

/// Represents a collection of indexes on a collection in ArangoDB.
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct IndexCollection {
    pub indexes: Vec<Index>,
}

/// Response from ArangoDB when deleting an index
#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct DeleteIndexResponse {
    pub id: String,
}