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
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// Copyright (c) DUSK NETWORK. All rights reserved.

use alloc::sync::Arc;
use core::convert::Infallible;
use rkyv::ser::Serializer;

use bytecheck::CheckBytes;
use rkyv::validation::validators::DefaultValidator;
use rkyv::{check_archived_root, Archive, Fallible, Serialize};

use crate::{Ident, Store, StoreProvider, StoreSerializer, Stored};

use super::{Token, TokenBuffer};

/// A clonable reference to a store
pub struct StoreRef<I> {
    inner: Arc<dyn Store<Identifier = I>>,
}

impl<I> StoreRef<I> {
    /// Creates a new StoreReference
    pub fn new<S: 'static + Store<Identifier = I>>(store: S) -> StoreRef<I> {
        StoreRef {
            inner: Arc::new(store),
        }
    }
}

impl<I> StoreRef<I> {
    /// Store a value, returning a `Stored` fat pointer that also carries a
    /// reference to the underlying storage with it    
    pub fn store<T>(&self, t: &T) -> Stored<T, I>
    where
        T: Serialize<StoreSerializer<I>>,
    {
        Stored::new(self.clone(), self.put(t))
    }

    /// Put a value into the store, returning an Ident.
    pub fn put<T>(&self, t: &T) -> Ident<T, I>
    where
        T: Serialize<StoreSerializer<I>>,
    {
        let mut ser = self.serializer();
        ser.serialize(t);
        let id = ser.commit();
        Ident::new(id)
    }

    /// Put raw bytes into the store, returning an Ident.
    pub fn put_raw(&self, bytes: &[u8]) -> I {
        let mut ser = self.serializer();
        // write the bytes using the `Serializer` directly.
        ser.write(bytes).unwrap();
        ser.commit()
    }

    /// Return a serializer associated with this store
    pub fn serializer(&self) -> StoreSerializer<I> {
        StoreSerializer::new(self.clone(), self.inner.request_buffer())
    }

    /// Gets a reference to an archived value
    pub fn get<T>(&self, ident: &Ident<T, I>) -> &T::Archived
    where
        T: Archive,
        T::Archived: for<'a> CheckBytes<DefaultValidator<'a>>,
    {
        let buffer = self.get_raw(ident.erase());

        let root = check_archived_root::<T>(buffer).unwrap();
        root
    }

    /// Gets a reference to the backing bytes of an archived value
    pub fn get_raw(&self, i: &I) -> &[u8] {
        self.inner.get(i)
    }

    /// Persist the storage to a backend
    pub fn persist(&self) -> Result<(), ()> {
        self.inner.persist()
    }

    /// Commit written data, returns an identifier
    pub fn commit(&self, buffer: &mut TokenBuffer) -> I {
        self.inner.commit(buffer)
    }

    /// Request extra space n the underlying buffer
    pub fn extend(&self, buffer: &mut TokenBuffer) -> Result<(), ()> {
        self.inner.extend(buffer)
    }

    /// Accept the token back
    pub fn return_token(&self, token: Token) {
        self.inner.return_token(token)
    }
}

impl<I> StoreProvider<I> for StoreRef<I> {
    fn store(&self) -> &StoreRef<I> {
        self
    }
}

impl<I> Clone for StoreRef<I> {
    fn clone(&self) -> Self {
        Self {
            inner: self.inner.clone(),
        }
    }
}

impl<I> Fallible for StoreRef<I> {
    type Error = Infallible;
}