use std::num::{NonZeroU32, NonZeroUsize};
use ruststream::runtime::{Declared, SubscriberBuilder, SubscriberSettings, Workers};
use super::queue::InboxQueue;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
#[must_use]
pub struct InboxThreads {
count: NonZeroUsize,
connections: NonZeroU32,
by_key: bool,
}
impl InboxThreads {
pub const fn new(count: NonZeroUsize) -> Self {
Self {
count,
connections: NonZeroU32::MIN,
by_key: false,
}
}
pub const fn by_key(mut self) -> Self {
self.by_key = true;
self
}
pub const fn connections(mut self, connections: NonZeroU32) -> Self {
self.connections = connections;
self
}
pub(crate) fn total_connections(&self) -> u64 {
u64::try_from(self.count.get())
.unwrap_or(u64::MAX)
.saturating_mul(u64::from(self.connections.get()))
}
pub(crate) const fn connections_each(&self) -> NonZeroU32 {
self.connections
}
pub(crate) const fn workers(&self) -> Workers {
if self.by_key {
Workers::threads_keyed(self.count)
} else {
Workers::threads(self.count)
}
}
}
#[doc(hidden)]
#[diagnostic::on_unimplemented(
message = "`.on_threads(..)` runs an `InboxQueue` subscription on threads with pools of their own",
label = "this registration does not subscribe through `InboxQueue`",
note = "a subscription by name takes the framework's `threads(n)`: subscribe with \
`InboxQueue::<Row>::new(..)` for threads with pools of their own"
)]
pub trait ThreadsStep {
type Out;
fn apply_threads(self, threads: InboxThreads) -> Self::Out;
}
impl<Def, Row, Mode, State, DefCodec> ThreadsStep
for SubscriberBuilder<Def, InboxQueue<Row, Mode>, State, DefCodec>
where
Def: Declared,
{
type Out = Self;
fn apply_threads(self, threads: InboxThreads) -> Self {
self.map_source(move |queue| queue.on_threads(threads))
}
}