use crate::{
crypto::{DetachedKey, Encrypted, Encrypter},
error::{Error, Result},
};
use async_std::sync::Arc;
use serde::{de::DeserializeOwned, Deserialize, Serialize};
use std::{
collections::BTreeMap,
fmt::Debug,
hash::Hash,
ops::{Deref, DerefMut},
};
#[derive(Serialize, Deserialize)]
pub(crate) struct EncryptedMap<K, V, Q>
where
K: Serialize + DeserializeOwned + Ord + PartialOrd + Hash + ToString,
V: Clone + DetachedKey<Q> + Serialize + DeserializeOwned,
Q: Encrypter<V>,
{
#[serde(bound(deserialize = "V: DeserializeOwned"))]
inner: BTreeMap<K, Encrypted<V, Q>>,
}
impl<K, V, Q> EncryptedMap<K, V, Q>
where
K: Serialize + DeserializeOwned + Ord + PartialOrd + Hash + ToString,
V: Clone + DetachedKey<Q> + Serialize + DeserializeOwned,
Q: Encrypter<V>,
{
pub(crate) fn new() -> Self {
Self {
inner: Default::default(),
}
}
pub(crate) fn open(&mut self, id: K, key: &Q) -> Result<()> {
match self.inner.get_mut(&id) {
Some(entry) => Ok(entry.open(key)?),
None => Err(Error::UnlockFailed { id: id.to_string() }),
}
}
pub(crate) fn close<P>(&mut self, id: K, key: P) -> Result<()>
where
P: Into<Option<Arc<Q>>>,
{
let key = key.into();
match self.inner.get_mut(&id) {
Some(entry) => {
let key = entry
.key()
.or(key)
.expect("No key provided for `open` operation");
Ok(entry.close(key)?)
}
None => Err(Error::UnlockFailed { id: id.to_string() }),
}
}
pub(crate) fn get(&self, id: K) -> Result<&V> {
match self.inner.get(&id) {
Some(Encrypted::Open(ref data)) => Ok(data),
Some(Encrypted::Closed(_)) => Err(Error::InternalError {
msg: "Tried reading ::Closed variant".into(),
}),
Some(Encrypted::Never(_)) => unreachable!(),
None => Err(Error::InternalError {
msg: "No data for key".into(),
}),
}
}
pub(crate) fn get_mut(&mut self, id: K) -> Result<&mut V> {
match self.inner.get_mut(&id) {
Some(Encrypted::Open(ref mut data)) => Ok(data),
Some(Encrypted::Closed(_)) => Err(Error::InternalError {
msg: "Tried reading ::Closed variant".into(),
}),
Some(Encrypted::Never(_)) => unreachable!(),
None => Err(Error::InternalError {
msg: "No data for key".into(),
}),
}
}
}
impl<K, V, Q> Deref for EncryptedMap<K, V, Q>
where
K: Serialize + DeserializeOwned + Ord + PartialOrd + Hash + ToString,
V: Clone + DetachedKey<Q> + Serialize + DeserializeOwned,
Q: Encrypter<V> + Debug,
{
type Target = BTreeMap<K, Encrypted<V, Q>>;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
impl<K, V, Q> DerefMut for EncryptedMap<K, V, Q>
where
K: Serialize + DeserializeOwned + Ord + PartialOrd + Hash + ToString,
V: Clone + DetachedKey<Q> + Serialize + DeserializeOwned,
Q: Encrypter<V> + Debug,
{
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.inner
}
}