use std::marker::PhantomData;
use crate::{Condition, Context, HandlerResult, Value};
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct ChannelLoad {
pub(crate) name: String,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ChannelMapLoad {
pub(crate) name: String,
pub(crate) instance: Option<String>,
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ChannelMessage<T> {
pub message_id: String,
pub value: T,
}
pub struct Channel<T> {
name: String,
marker: PhantomData<fn() -> T>,
}
impl<T> Channel<T> {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
marker: PhantomData,
}
}
pub fn publish(&self, context: &mut Context, value: T) -> HandlerResult<()>
where
T: Value,
{
context.publish(self, value)
}
pub fn delete(&self, context: &mut Context, message_id: &str) -> HandlerResult<()> {
context.delete_channel_message(self, message_id)
}
pub fn size(&self, context: &Context) -> HandlerResult<usize> {
context.channel_size(self)
}
pub fn pending_messages(&self, context: &Context) -> HandlerResult<Vec<ChannelMessage<T>>>
where
T: Value,
{
context.pending_channel_messages(self)
}
pub fn find_pending_message(
&self,
context: &Context,
message_id: &str,
) -> HandlerResult<Option<ChannelMessage<T>>>
where
T: Value,
{
Ok(self
.pending_messages(context)?
.into_iter()
.find(|message| message.message_id == message_id))
}
pub fn condition_results(&self, context: &Context) -> HandlerResult<Vec<T>>
where
T: Value,
{
context.channel_results(self)
}
pub fn for_one(&self) -> Condition {
self.range(Some(1), Some(1))
}
pub fn for_n(&self, count: usize) -> Condition {
self.range(Some(count), Some(count))
}
pub fn at_least(&self, count: usize) -> Condition {
self.range(Some(count), None)
}
pub fn at_most(&self, count: usize) -> Condition {
self.range(None, Some(count))
}
pub fn range(&self, at_least: Option<usize>, at_most: Option<usize>) -> Condition {
Condition::channel(self.name.clone(), None, at_least, at_most)
}
pub fn when_empty(&self) -> ChannelGuard {
ChannelGuard {
name: self.name.clone(),
instance: None,
}
}
pub(crate) fn name(&self) -> &str {
&self.name
}
}
impl<T> Clone for Channel<T> {
fn clone(&self) -> Self {
Self {
name: self.name.clone(),
marker: PhantomData,
}
}
}
pub struct ChannelMap<T> {
name: String,
marker: PhantomData<fn() -> T>,
}
impl<T> ChannelMap<T> {
pub fn new(name: impl Into<String>) -> Self {
Self {
name: name.into(),
marker: PhantomData,
}
}
pub fn load_messages(&self, instance: impl Into<String>) -> ChannelMapLoad {
ChannelMapLoad {
name: self.name.clone(),
instance: Some(instance.into()),
}
}
pub fn publish(&self, context: &mut Context, instance: &str, value: T) -> HandlerResult<()>
where
T: Value,
{
context.publish_map(self, instance, value)
}
pub fn delete(
&self,
context: &mut Context,
instance: &str,
message_id: &str,
) -> HandlerResult<()> {
context.delete_channel_map_message(self, instance, message_id)
}
pub fn size(&self, context: &Context, instance: &str) -> HandlerResult<usize> {
context.channel_map_size(self, instance)
}
pub fn pending_messages(
&self,
context: &Context,
instance: &str,
) -> HandlerResult<Vec<ChannelMessage<T>>>
where
T: Value,
{
context.pending_channel_map_messages(self, instance)
}
pub fn find_pending_message(
&self,
context: &Context,
instance: &str,
message_id: &str,
) -> HandlerResult<Option<ChannelMessage<T>>>
where
T: Value,
{
Ok(self
.pending_messages(context, instance)?
.into_iter()
.find(|message| message.message_id == message_id))
}
pub fn map_size(&self, context: &Context) -> HandlerResult<usize> {
Ok(self.all_instance_keys(context)?.len())
}
pub fn all_instance_keys(&self, context: &Context) -> HandlerResult<Vec<String>> {
context.channel_map_keys(self)
}
pub fn condition_results(&self, context: &Context, instance: &str) -> HandlerResult<Vec<T>>
where
T: Value,
{
context.channel_map_results(self, instance)
}
pub fn for_one(&self, instance: &str) -> Condition {
self.range(instance, Some(1), Some(1))
}
pub fn for_n(&self, instance: &str, count: usize) -> Condition {
self.range(instance, Some(count), Some(count))
}
pub fn at_least(&self, instance: &str, count: usize) -> Condition {
self.range(instance, Some(count), None)
}
pub fn at_most(&self, instance: &str, count: usize) -> Condition {
self.range(instance, None, Some(count))
}
pub fn range(
&self,
instance: &str,
at_least: Option<usize>,
at_most: Option<usize>,
) -> Condition {
crate::registry::assert_map_instance(instance);
Condition::channel(
self.name.clone(),
Some(instance.to_string()),
at_least,
at_most,
)
}
pub fn when_empty(&self, instance: &str) -> ChannelGuard {
crate::registry::assert_map_instance(instance);
ChannelGuard {
name: self.name.clone(),
instance: Some(instance.to_string()),
}
}
pub(crate) fn name(&self) -> &str {
&self.name
}
}
impl<T> Clone for ChannelMap<T> {
fn clone(&self) -> Self {
Self {
name: self.name.clone(),
marker: PhantomData,
}
}
}
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct ChannelGuard {
name: String,
instance: Option<String>,
}
impl ChannelGuard {
pub(crate) fn physical_name(&self) -> String {
match self.instance.as_deref() {
Some(instance) => crate::registry::physical_name(&self.name, instance),
None => self.name.clone(),
}
}
}