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
//! [`CollectionViewSchema`](crate::schema::CollectionViewSchema) 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::schema::{Collection, SerializedCollection};
32

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

            
229
impl<'a> AsRef<Header> for BorrowedDocument<'a> {
230
    fn as_ref(&self) -> &Header {
231
        &self.header
232
    }
233
}
234

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

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