hcl_compat_uefi_nvram_storage/
storage_backend.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Trait for abstracting the backend used for NVRAM storage
5
6use thiserror::Error;
7
8/// Error when accessing a [`StorageBackend`]
9#[derive(Error, Debug)]
10#[error("error accessing nvram storage backend")]
11pub struct StorageBackendError(#[from] anyhow::Error);
12
13impl StorageBackendError {
14    /// Create a new [`StorageBackendError`]
15    pub fn new(e: impl Into<anyhow::Error>) -> StorageBackendError {
16        Self(e.into())
17    }
18}
19
20/// Storage backend for accessing the NVRAM
21#[async_trait::async_trait]
22pub trait StorageBackend: Send + Sync {
23    /// Write `data` to a non-volatile storage medium.
24    async fn persist(&mut self, data: Vec<u8>) -> Result<(), StorageBackendError>;
25
26    /// Read any previously written `data`. Returns `None` if no data exists.
27    async fn restore(&mut self) -> Result<Option<Vec<u8>>, StorageBackendError>;
28}
29
30// Boilerplate: forward `StorageBackend` methods for `Box<dyn StorageBackend>`
31#[async_trait::async_trait]
32impl StorageBackend for Box<dyn StorageBackend> {
33    async fn persist(&mut self, data: Vec<u8>) -> Result<(), StorageBackendError> {
34        (**self).persist(data).await
35    }
36
37    async fn restore(&mut self) -> Result<Option<Vec<u8>>, StorageBackendError> {
38        (**self).restore().await
39    }
40}
41
42// Boilerplate: forward `StorageBackend` methods for `&mut StorageBackend`
43#[async_trait::async_trait]
44impl<T> StorageBackend for &mut T
45where
46    T: StorageBackend,
47{
48    async fn persist(&mut self, data: Vec<u8>) -> Result<(), StorageBackendError> {
49        (**self).persist(data).await
50    }
51
52    async fn restore(&mut self) -> Result<Option<Vec<u8>>, StorageBackendError> {
53        (**self).restore().await
54    }
55}