async_flow/model/
outputs.rs1use super::{OutputPortId, PortId};
4use core::{
5 any::type_name,
6 marker::PhantomData,
7 ops::Bound,
8 sync::atomic::{AtomicIsize, Ordering},
9};
10
11pub type Output<T> = Outputs<T, 1, 0>;
15
16#[derive(Clone, Eq, Hash, Ord, PartialEq, PartialOrd)]
20pub struct Outputs<T, const MAX: isize = -1, const MIN: isize = 0>(OutputPortId, PhantomData<T>);
21
22impl<T, const MAX: isize, const MIN: isize> Default for Outputs<T, MAX, MIN> {
23 fn default() -> Self {
24 static COUNTER: AtomicIsize = AtomicIsize::new(1);
25 let id = COUNTER.fetch_add(1, Ordering::AcqRel);
26 Self(OutputPortId(id), PhantomData)
27 }
28}
29
30impl<T, const MAX: isize, const MIN: isize> core::fmt::Debug for Outputs<T, MAX, MIN> {
31 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
32 f.debug_tuple(&alloc::format!("Outputs<{}>", type_name::<T>()))
33 .field(&self.0)
34 .finish()
35 }
36}
37
38impl<T, const MAX: isize, const MIN: isize> Outputs<T, MAX, MIN> {
39 pub fn id(&self) -> OutputPortId {
40 self.0
41 }
42
43 pub fn cardinality() -> (Bound<usize>, Bound<usize>) {
45 assert!(MIN >= 0);
46 assert!(MAX >= -1);
47 use Bound::*;
48 match (MIN, MAX) {
49 (min, -1) => (Included(min as _), Unbounded),
50 (min, max) => (Included(min as _), Included(max as _)),
51 }
52 }
53}
54
55impl<T, const MAX: isize, const MIN: isize> Into<OutputPortId> for &Outputs<T, MAX, MIN> {
56 fn into(self) -> OutputPortId {
57 self.0
58 }
59}
60
61impl<T, const MAX: isize, const MIN: isize> Into<PortId> for &Outputs<T, MAX, MIN> {
62 fn into(self) -> PortId {
63 self.0.into()
64 }
65}