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
153
154
155
156
157
158
159
160
161
162
163
164
165
use crate::Record;

/// Trait for structures that can be stored in Database as a ArangoDB EdgeCollection.
/// The trait must be implemented to be used as a edge record in [`DatabaseRecord`].
///
/// # How to use
///
/// ## Declaration
///
/// A structure deriving from `EdgeRecord` **MUST** contain two string fields:
/// * `_from` - The id of the source document
/// * `_to` - The id of the target document
/// Or the compilation will fail.
///
/// On creation or save these two fields must be valid ArangoDB `Object ID` formatted as:
/// > `CollectionName/DocumentKey`
///
/// (Example: "User/123")
/// >
/// ## Creation
///
/// To create a edge between two existing [`DatabaseRecord`] you can use the following process:
///
/// ```rust no_run
/// # use aragog::{DatabaseRecord, EdgeRecord, Record, DatabaseConnectionPool};
/// # use serde::{Serialize, Deserialize, de::DeserializeOwned};
/// #
/// #[derive(Clone, Record, Serialize, Deserialize)]
/// struct Character {}
///
/// #[derive(Clone, EdgeRecord, Record, Serialize, Deserialize)]
/// struct Edge {
///     _from: String,
///     _to: String,
///     description: String,
/// }
/// # #[tokio::main]
/// # async fn main() {
/// # let db_accessor = DatabaseConnectionPool::builder().build().await.unwrap();
///
/// let record_a = Character::find("123", &db_accessor).await.unwrap();
/// let record_b = Character::find("234", &db_accessor).await.unwrap();
///
/// let edge_record = DatabaseRecord::link(&record_a, &record_b, &db_accessor, |_from, _to| {
///     Edge { _from, _to, description: "description".to_string() }
/// }).await.unwrap();
/// # }
/// ```
///
/// [`DatabaseRecord`]: struct.DatabaseRecord.html
pub trait EdgeRecord: Record {
    /// Retrieves the struct `_from` field
    fn _from(&self) -> &String;

    /// Retrieves the struct `_to` field
    fn _to(&self) -> &String;

    /// Parses the `_from()` returned `id` and returns the document `key`
    ///
    /// # Panic
    ///
    /// The method will panic if the stored `id` is not formatted correctly (`String`/`String`)
    ///
    /// # Example
    ///```rust
    /// # use serde::{Serialize, Deserialize, de::DeserializeOwned};
    /// use aragog::{EdgeRecord, Record, Validate, DatabaseRecord};
    ///
    /// #[derive(EdgeRecord, Record, Clone, Serialize, Deserialize, Validate)]
    /// struct EdgeModel {
    ///     pub _from: String,
    ///     pub _to: String,
    /// }
    ///
    /// let edge = EdgeModel {
    ///    _from: "User/123".to_string(),
    ///    _to: "Client/345".to_string(),
    /// };
    /// assert_eq!(edge._from_key(), "123".to_string());
    /// ```
    fn _from_key(&self) -> String {
        self._from().split('/').last().unwrap().to_string()
    }

    /// Parses the `_to()` returned `id` and returns the document `key`
    ///
    /// # Panic
    ///
    /// The method will panic if the stored `id` is not formatted correctly (`String`/`String`)
    ///
    /// # Example
    ///```rust
    /// # use serde::{Serialize, Deserialize, de::DeserializeOwned};
    /// use aragog::{EdgeRecord, Record, Validate, DatabaseRecord};
    ///
    /// #[derive(EdgeRecord, Record, Clone, Serialize, Deserialize, Validate)]
    /// struct EdgeModel {
    ///     pub _from: String,
    ///     pub _to: String,
    /// }
    ///
    /// let edge = EdgeModel {
    ///    _from: "User/123".to_string(),
    ///    _to: "Client/345".to_string(),
    /// };
    /// assert_eq!(edge._to_key(), "345".to_string());
    /// ```
    fn _to_key(&self) -> String {
        self._to().split('/').last().unwrap().to_string()
    }

    /// Parses the `_to()` returned `id` and returns the document collection name
    ///
    /// # Panic
    ///
    /// The method will panic if the stored `id` is not formatted correctly (`String`/`String`)
    ///
    /// # Example
    ///```rust
    /// # use serde::{Serialize, Deserialize, de::DeserializeOwned};
    /// use aragog::{EdgeRecord, Record, Validate, DatabaseRecord};
    ///
    /// #[derive(EdgeRecord, Record, Clone, Serialize, Deserialize, Validate)]
    /// struct EdgeModel {
    ///     pub _from: String,
    ///     pub _to: String,
    /// }
    ///
    /// let edge = EdgeModel {
    ///    _from: "User/123".to_string(),
    ///    _to: "Client/345".to_string(),
    /// };
    /// assert_eq!(edge._to_collection_name(), "Client".to_string());
    /// ```
    fn _to_collection_name(&self) -> String {
        self._to().split('/').next().unwrap().to_string()
    }

    /// Parses the `_from()` returned `id` and returns the document collection name
    ///
    /// # Panic
    ///
    /// The method will panic if the stored `id` is not formatted correctly (`String`/`String`)
    ///
    /// # Example
    ///```rust
    /// # use serde::{Serialize, Deserialize, de::DeserializeOwned};
    /// use aragog::{EdgeRecord, Record, Validate, DatabaseRecord};
    ///
    /// #[derive(EdgeRecord, Record, Clone, Serialize, Deserialize, Validate)]
    /// struct EdgeModel {
    ///     pub _from: String,
    ///     pub _to: String,
    /// }
    ///
    /// let edge = EdgeModel {
    ///    _from: "User/123".to_string(),
    ///    _to: "Client/345".to_string(),
    /// };
    /// assert_eq!(edge._from_collection_name(), "User".to_string());
    /// ```
    fn _from_collection_name(&self) -> String {
        self._from().split('/').next().unwrap().to_string()
    }
}