mod sent;
pub use sent::SentShareRepo;
pub use sent::InMemorySentShareRepo;
use std::{
collections::HashMap,
sync::{Arc, Mutex},
fmt::Debug
};
use ocm_types::{common::OcmAddress, error::Error, share::{NewShare, SendingServer}};
use serde::Serialize;
use super::protocols::MultiProtocol;
pub type ReceivedShare = (NewShare, MultiProtocol);
pub trait ReceivedShareRepo: Debug + Clone + Send + Sync {
fn insert(
&self,
sending_server: SendingServer,
share: ReceivedShare,
) -> impl std::future::Future<Output = Result<Option<ReceivedShare>, ShareRepoError>>
+ std::marker::Send
+ std::marker::Sized;
fn get(
&self,
sending_server: SendingServer,
provider_id: &str,
) -> impl std::future::Future<Output = Result<ReceivedShare, ShareRepoError>>
+ std::marker::Send
+ std::marker::Sized;
fn get_by_sender(
&self,
sender: &OcmAddress,
) -> impl std::future::Future<Output = Result<Vec<ReceivedShare>, ShareRepoError>>
+ std::marker::Send
+ std::marker::Sized;
fn get_by_recipient(
&self,
recipient: &OcmAddress,
) -> impl std::future::Future<Output = Result<Vec<ReceivedShare>, ShareRepoError>>
+ std::marker::Send
+ std::marker::Sized;
fn remove(
&self,
sending_server: SendingServer,
provider_id: &str,
) -> impl std::future::Future<Output = Result<ReceivedShare, ShareRepoError>>
+ std::marker::Send
+ std::marker::Sized;
}
#[derive(Debug, Clone, Serialize)]
#[serde(into = "ocm_types::error::Error")]
pub enum ShareRepoError {
NotFound,
}
impl ShareRepoError {
pub fn status_code(&self) -> http::StatusCode {
match self {
ShareRepoError::NotFound => http::StatusCode::NOT_FOUND,
}
}
}
impl From<ShareRepoError> for Error {
fn from(value: ShareRepoError) -> Self {
match value {
ShareRepoError::NotFound => Self {
message: "SHARE_NOT_FOUND".to_string(),
validation_errors: vec![],
},
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct ProviderId(String);
impl From<ProviderId> for String{
fn from(value: ProviderId) -> Self {
value.0
}
}
impl From<String> for ProviderId {
fn from(value: String) -> Self {
Self(value)
}
}
impl AsRef<str> for ProviderId {
fn as_ref(&self) -> &str {
&self.0
}
}
#[derive(Debug, Clone, Default)]
pub struct InMemoryShareRepo {
map: Arc<Mutex<HashMap<(SendingServer, ProviderId), ReceivedShare>>>,
}
impl ReceivedShareRepo for InMemoryShareRepo {
async fn insert(&self, sending_server: SendingServer, share: ReceivedShare) -> Result<Option<ReceivedShare>, ShareRepoError> {
Ok(self
.map
.lock()
.unwrap()
.insert((sending_server, ProviderId(share.0.provider_id.clone())), share))
}
async fn get(&self, sending_server: SendingServer, provider_id: &str) -> Result<ReceivedShare, ShareRepoError> {
Ok(self
.map
.lock()
.unwrap()
.get(&(sending_server, ProviderId(provider_id.to_owned())))
.cloned()
.ok_or(ShareRepoError::NotFound))?
}
async fn get_by_sender(&self, sender: &OcmAddress) -> Result<Vec<ReceivedShare>, ShareRepoError> {
Ok(self
.map
.lock()
.unwrap()
.values()
.filter(|share| &share.0.sender == sender)
.cloned()
.collect())
}
async fn get_by_recipient(&self, recipient: &OcmAddress) -> Result<Vec<ReceivedShare>, ShareRepoError> {
Ok(self
.map
.lock()
.unwrap()
.values()
.filter(|share| &share.0.share_with == recipient)
.cloned()
.collect())
}
async fn remove(&self, sending_server: SendingServer, provider_id: &str) -> Result<ReceivedShare, ShareRepoError> {
Ok(self
.map
.lock()
.unwrap()
.remove(&(sending_server, ProviderId(provider_id.to_owned())))
.ok_or(ShareRepoError::NotFound))?
}
}