1 use std
::future
::Future
;
5 use anyhow
::{bail, Error}
;
7 use pbs_datastore
::crypt_config
::{CryptConfig, CryptMode}
;
8 use pbs_datastore
::data_blob
::DataBlob
;
9 use pbs_datastore
::read_chunk
::{ReadChunk, AsyncReadChunk}
;
11 use super::datastore
::DataStore
;
14 pub struct LocalChunkReader
{
15 store
: Arc
<DataStore
>,
16 crypt_config
: Option
<Arc
<CryptConfig
>>,
17 crypt_mode
: CryptMode
,
20 impl LocalChunkReader
{
21 pub fn new(store
: Arc
<DataStore
>, crypt_config
: Option
<Arc
<CryptConfig
>>, crypt_mode
: CryptMode
) -> Self {
29 fn ensure_crypt_mode(&self, chunk_mode
: CryptMode
) -> Result
<(), Error
> {
30 match self.crypt_mode
{
31 CryptMode
::Encrypt
=> {
33 CryptMode
::Encrypt
=> Ok(()),
34 CryptMode
::SignOnly
| CryptMode
::None
=> bail
!("Index and chunk CryptMode don't match."),
37 CryptMode
::SignOnly
| CryptMode
::None
=> {
39 CryptMode
::Encrypt
=> bail
!("Index and chunk CryptMode don't match."),
40 CryptMode
::SignOnly
| CryptMode
::None
=> Ok(()),
47 impl ReadChunk
for LocalChunkReader
{
48 fn read_raw_chunk(&self, digest
: &[u8; 32]) -> Result
<DataBlob
, Error
> {
49 let chunk
= self.store
.load_chunk(digest
)?
;
50 self.ensure_crypt_mode(chunk
.crypt_mode()?
)?
;
54 fn read_chunk(&self, digest
: &[u8; 32]) -> Result
<Vec
<u8>, Error
> {
55 let chunk
= ReadChunk
::read_raw_chunk(self, digest
)?
;
57 let raw_data
= chunk
.decode(self.crypt_config
.as_ref().map(Arc
::as_ref
), Some(digest
))?
;
63 impl AsyncReadChunk
for LocalChunkReader
{
64 fn read_raw_chunk
<'a
>(
67 ) -> Pin
<Box
<dyn Future
<Output
= Result
<DataBlob
, Error
>> + Send
+ 'a
>> {
69 let (path
, _
) = self.store
.chunk_path(digest
);
71 let raw_data
= tokio
::fs
::read(&path
).await?
;
73 let chunk
= DataBlob
::load_from_reader(&mut &raw_data
[..])?
;
74 self.ensure_crypt_mode(chunk
.crypt_mode()?
)?
;
83 ) -> Pin
<Box
<dyn Future
<Output
= Result
<Vec
<u8>, Error
>> + Send
+ 'a
>> {
85 let chunk
= AsyncReadChunk
::read_raw_chunk(self, digest
).await?
;
87 let raw_data
= chunk
.decode(self.crypt_config
.as_ref().map(Arc
::as_ref
), Some(digest
))?
;
89 // fixme: verify digest?