1
//! Types for interacting with `Document`s.
2
//!
3
//! A document is a stored value in a [`Collection`]. Each document has a
4
//! [`Header`], which contains a unique ID and information about the currently
5
//! stored revision. BonsaiDb adds extra protections by requiring update
6
//! operations to include the document's current header. If the document header
7
//! doesn't match the currently stored information,
8
//! [`Error::DocumentConflict`](crate::Error::DocumentConflict) will be
9
//! returned.
10
//!
11
//! The lower-level interface for BonsaiDb uses [`OwnedDocument`] and
12
//! [`BorrowedDocument`]. These types contain a buffer of bytes that have been
13
//! inserted into a collection previously. This interface is useful if you are
14
//! wanting to do borrowing or zero-copy deserialization, as the handling of the
15
//! bytes is left up to the user. Views implemented using
16
//! [`ViewSchema`](crate::schema::ViewSchema) receive a [`BorrowedDocument`]
17
//! parameter to the map function.
18
//!
19
//! The higher-level interface uses [`CollectionDocument<T>`] which
20
//! automatically serializes and deserialized from
21
//! [`OwnedDocument`]/[`BorrowedDocument`] using the [`SerializedCollection`]
22
//! trait. This interface is recommended for most users, as it is significantly
23
//! more ergonomic. Views implemented using
24
//! [`CollectionMapReduce`](crate::schema::CollectionMapReduce) receive a
25
//! [`CollectionDocument<T>`] parameter to the map function.
26
use std::borrow::Cow;
27

            
28
use arc_bytes::serde::{Bytes, CowBytes};
29
use serde::{Deserialize, Serialize};
30

            
31
use crate::key::KeyEncoding;
32
use crate::schema::{Collection, SerializedCollection};
33

            
34
mod collection;
35
mod header;
36
mod id;
37
mod revision;
38
pub use self::collection::{CollectionDocument, OwnedDocuments};
39
pub use self::header::{AnyHeader, CollectionHeader, Emit, HasHeader, Header};
40
pub use self::id::{DocumentId, InvalidHexadecimal};
41
pub use self::revision::Revision;
42
/// Contains a serialized document in the database.
43
8461935
#[derive(Clone, Debug, Serialize, Deserialize)]
44
pub struct BorrowedDocument<'a> {
45
    /// The header of the document, which contains the id and `Revision`.
46
    pub header: Header,
47

            
48
    /// The serialized bytes of the stored item.
49
    #[serde(borrow)]
50
    pub contents: CowBytes<'a>,
51
}
52

            
53
/// Contains a serialized document in the database.
54
1972200
#[derive(Clone, Debug, Serialize, Deserialize)]
55
pub struct OwnedDocument {
56
    /// The header of the document, which contains the id and `Revision`.
57
    pub header: Header,
58

            
59
    /// The serialized bytes of the stored item.
60
    pub contents: Bytes,
61
}
62

            
63
/// Common interface of a document in BonsaiDb.
64
pub trait Document<C>: Sized
65
where
66
    C: Collection,
67
{
68
    /// The bytes type used in the interface.
69
    type Bytes;
70

            
71
    /// Returns the unique key for this document.
72
    fn id(&self) -> &DocumentId;
73
    /// Returns the header of this document.
74
    fn header(&self) -> AnyHeader<C::PrimaryKey>;
75
    /// Sets the header to the new header.
76
    fn set_header(&mut self, header: Header) -> Result<(), crate::Error>;
77
    /// Sets the header to the new collection header.
78
8
    fn set_collection_header(
79
8
        &mut self,
80
8
        header: CollectionHeader<C::PrimaryKey>,
81
8
    ) -> Result<(), crate::Error> {
82
8
        self.set_header(Header::try_from(header)?)
83
8
    }
84
    /// Returns the contents of this document, serialized.
85
    fn bytes(&self) -> Result<Vec<u8>, crate::Error>;
86
    /// Retrieves `contents` through deserialization into the type `D`.
87
    fn contents(&self) -> Result<C::Contents, crate::Error>
88
    where
89
        C: SerializedCollection;
90
    /// Stores `contents` into this document.
91
    fn set_contents(&mut self, contents: C::Contents) -> Result<(), crate::Error>
92
    where
93
        C: SerializedCollection;
94
}
95

            
96
impl<'a> AsRef<[u8]> for BorrowedDocument<'a> {
97
    fn as_ref(&self) -> &[u8] {
98
        &self.contents
99
    }
100
}
101

            
102
impl<'a, C> Document<C> for BorrowedDocument<'a>
103
where
104
    C: Collection,
105
{
106
    type Bytes = CowBytes<'a>;
107

            
108
504763
    fn contents(&self) -> Result<C::Contents, crate::Error>
109
504763
    where
110
504763
        C: SerializedCollection,
111
504763
    {
112
504763
        <C as SerializedCollection>::deserialize(&self.contents)
113
504763
    }
114

            
115
    fn set_contents(&mut self, contents: C::Contents) -> Result<(), crate::Error>
116
    where
117
        C: SerializedCollection,
118
    {
119
        self.contents = CowBytes::from(<C as SerializedCollection>::serialize(&contents)?);
120
        Ok(())
121
    }
122

            
123
8
    fn header(&self) -> AnyHeader<C::PrimaryKey> {
124
8
        AnyHeader::Serialized(self.header.clone())
125
8
    }
126

            
127
    fn set_header(&mut self, header: Header) -> Result<(), crate::Error> {
128
        self.header = header;
129
        Ok(())
130
    }
131

            
132
8
    fn bytes(&self) -> Result<Vec<u8>, crate::Error> {
133
8
        Ok(self.contents.to_vec())
134
8
    }
135

            
136
    fn id(&self) -> &DocumentId {
137
        &self.header.id
138
    }
139
}
140

            
141
impl<C> Document<C> for OwnedDocument
142
where
143
    C: Collection,
144
{
145
    type Bytes = Vec<u8>;
146

            
147
1053
    fn contents(&self) -> Result<C::Contents, crate::Error>
148
1053
    where
149
1053
        C: SerializedCollection,
150
1053
    {
151
1053
        <C as SerializedCollection>::deserialize(&self.contents)
152
1053
    }
153

            
154
541
    fn set_contents(&mut self, contents: C::Contents) -> Result<(), crate::Error>
155
541
    where
156
541
        C: SerializedCollection,
157
541
    {
158
541
        self.contents = Bytes::from(<C as SerializedCollection>::serialize(&contents)?);
159
541
        Ok(())
160
541
    }
161

            
162
8
    fn id(&self) -> &DocumentId {
163
8
        &self.header.id
164
8
    }
165

            
166
6559
    fn header(&self) -> AnyHeader<C::PrimaryKey> {
167
6559
        AnyHeader::Serialized(self.header.clone())
168
6559
    }
169

            
170
6543
    fn set_header(&mut self, header: Header) -> Result<(), crate::Error> {
171
6543
        self.header = header;
172
6543
        Ok(())
173
6543
    }
174

            
175
6567
    fn bytes(&self) -> Result<Vec<u8>, crate::Error> {
176
6567
        Ok(self.contents.to_vec())
177
6567
    }
178
}
179

            
180
impl AsRef<Header> for OwnedDocument {
181
    fn as_ref(&self) -> &Header {
182
        &self.header
183
    }
184
}
185

            
186
impl AsMut<Header> for OwnedDocument {
187
    fn as_mut(&mut self) -> &mut Header {
188
        &mut self.header
189
    }
190
}
191

            
192
impl AsRef<[u8]> for OwnedDocument {
193
    fn as_ref(&self) -> &[u8] {
194
        &self.contents
195
    }
196
}
197

            
198
impl<'a> BorrowedDocument<'a> {
199
    /// Returns a new instance with the id and content bytes.
200
780565
    pub fn new<Contents: Into<CowBytes<'a>>>(id: DocumentId, contents: Contents) -> Self {
201
780565
        let contents = contents.into();
202
780565
        let revision = Revision::new(&contents);
203
780565
        Self {
204
780565
            header: Header { id, revision },
205
780565
            contents,
206
780565
        }
207
780565
    }
208

            
209
    /// Returns a new instance with `contents`, after serializing.
210
527
    pub fn with_contents<C, PrimaryKey>(
211
527
        id: &PrimaryKey,
212
527
        contents: &C::Contents,
213
527
    ) -> Result<Self, crate::Error>
214
527
    where
215
527
        C: SerializedCollection,
216
527
        PrimaryKey: KeyEncoding<C::PrimaryKey> + ?Sized,
217
527
    {
218
527
        let contents = <C as SerializedCollection>::serialize(contents)?;
219
527
        Ok(Self::new(DocumentId::new(id)?, contents))
220
527
    }
221

            
222
    /// Converts this document to an owned document.
223
    #[must_use]
224
1013080
    pub fn into_owned(self) -> OwnedDocument {
225
1013080
        OwnedDocument {
226
1013080
            header: self.header,
227
1013080
            contents: Bytes::from(self.contents),
228
1013080
        }
229
1013080
    }
230
}
231

            
232
impl<'a> AsRef<Header> for BorrowedDocument<'a> {
233
    fn as_ref(&self) -> &Header {
234
        &self.header
235
    }
236
}
237

            
238
impl<'a> AsMut<Header> for BorrowedDocument<'a> {
239
    fn as_mut(&mut self) -> &mut Header {
240
        &mut self.header
241
    }
242
}
243

            
244
/// The ID of an encryption key.
245
513659
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
246
pub enum KeyId {
247
    /// A key with no id.
248
    None,
249
    /// The master key of the vault.
250
    Master,
251
    /// A specific named key in the vault.
252
    Id(Cow<'static, str>),
253
}