async_recorder/
storage.rs

1use std::ops::Range;
2
3use async_trait::async_trait;
4
5/// Can save records asynchronously
6#[async_trait]
7pub trait Storage {
8    /// Records saved in the storage
9    type Record;
10
11    /// Describes the desired data for the load operation. Usefull for e.g. applying filters.
12    type Query;
13
14    /// Saves all the records to the persistence backend. Note that this method is infallible. This
15    /// implies that the responsibility of handling errors lies with the implementation of this
16    /// trait. So it is up to the implementation to decide how often to retry before (if ever)
17    /// giving up. What to log and so on.
18    ///
19    /// `records` contains all the records which are to be persisted with this call to save. The
20    /// records are passed in a `Vec` rather than in a single call to enable bulk insertion. They
21    /// are also passed in a `Vec` rather than a slice (`&[Record]`) in order to enable taking
22    /// ownership of each record and avoid cloning. Finally it is a `&mut Vec` rather than a buffer
23    /// so we can reuse it, without having to reallocate it a lot during the lifetime of our
24    /// application.
25    async fn save(&mut self, records: &mut Vec<Self::Record>);
26
27    /// Load the contents of the storage as a list of records.
28    async fn load(&mut self, query: Self::Query) -> Vec<Self::Record>;
29}
30
31/// This implementation is usefull for using as a fake for testing. In production you are more
32/// likely want to talk to a database.
33#[async_trait]
34impl<T> Storage for Vec<T>
35where
36    T: Send + Clone,
37{
38    type Query = Range<usize>;
39    type Record = T;
40
41    async fn save(&mut self, records: &mut Vec<T>) {
42        self.append(records);
43    }
44
45    async fn load(&mut self, query: Range<usize>) -> Vec<T> {
46        self[query].to_owned()
47    }
48}
49
50#[async_trait]
51impl<Q, R> Storage for Box<dyn Storage<Query = Q, Record = R> + Send> where Q: Send, R: Send {
52    type Query = Q;
53    type Record = R;
54
55    async fn save(&mut self, records: &mut Vec<R>) {
56        (**self).save(records).await
57    }
58
59    async fn load(&mut self, query: Q) -> Vec<R> {
60        (**self).load(query).await
61    }
62}